/*
* This file is part of the URI Template library.
*
* For licensing information please see the file license.txt included in the release.
* A copy of this licence can also be found at
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/
package org.weborganic.furi;
import java.util.Hashtable;
import java.util.Map;
/**
* A convenience class is to bind variables to resolvers in a set of URI patterns.
*
* Variables can be bound to a resolver by type or by name.
*
* To assign a {@link VariableResolver} to variables of a specific type, use {@link #bindType(String, VariableResolver)}.
*
* The following example will bind all variables typed <code>int</code> to return the corresponding integer value.
* <pre>
* VariableBinder binder = new VariableBinder();
* b.bindType("int", new VariableResolver(){
* public boolean exists(String v) {return v.matches("\\d+");}
* public Integer resolve(String v) {return exists(v)? Integer.valueOf(v) : null;};
* });
* </pre>
*
* To assign a {@link VariableResolver} to variables of a specific name, use {@link #bindName(String, VariableResolver)}.
*
* The following example will bind all variables typed <code>int</code> to return the corresponding integer value.
* <pre>
* VariableBinder binder = new VariableBinder();
* b.bindName("name", new VariableResolver(){
* public boolean exists(String v) {return true;}
* public Integer resolve(String v) {return exists(v)? Integer.valueOf(v) : null;};
* });
* </pre>
*
*
* @author Christophe Lauret
* @version 11 June 2009
*/
public class VariableBinder {
/**
* The default resolver accepts everything and resolves all values to themselves.
*/
private final static VariableResolver DEFAULT_RESOLVER = new VariableResolver() {
public boolean exists(String value) {
return true;
}
public Object resolve(String value) {
return value;
}
};
/**
* Maps a variable names to a resolver.
*/
private Map<String, VariableResolver> _byname = new Hashtable<String, VariableResolver>();
/**
* Maps a variable types to a resolver.
*/
private Map<String, VariableResolver> _bytype = new Hashtable<String, VariableResolver>();
/**
* Binds the variables with the specified name to the specified resolver.
*
* @deprecated use #bindName() or #bindType() instead
*
* @param name The name of the variable.
* @param resolver The resolver to use with these variables.
*/
public void bind(String name, VariableResolver resolver) {
this._byname.put(name, resolver);
}
/**
* Binds the variables with the specified name to the specified resolver.
*
* @param name The name of the variable.
* @param resolver The resolver to use with these variables.
*/
public void bindName(String name, VariableResolver resolver) {
this._byname.put(name, resolver);
}
/**
* Binds the variables with the specified name to the specified resolver.
*
* @param type The variable type.
* @param resolver The resolver to use with these variables.
*/
public void bindType(String type, VariableResolver resolver) {
this._bytype.put(type, resolver);
}
/**
* Returns the resolver used for the variable of the specified name or type.
*
* <p>By default, looks for the resolver assigned to the specified variable name; if no resolver
* is bound to the variable name, it will return the resolver bound to the given variable type.
*
* <p>This method does not return <code>null</code>. If the specified variable name or type is not
* bound to any resolver the default resolver if returned instead.
*
* @param name The name of the variable.
* @param type The type of the variable.
*
* @return the corresponding resolver.
*/
public VariableResolver getResolver(String name, VariableType type) {
VariableResolver resolver = this._byname.get(name);
// try to find a resolver by type
if (resolver == null && type != null) {
resolver = this._bytype.get(type.getName());
}
// fall back on the default otherwise
return resolver != null ? resolver : DEFAULT_RESOLVER;
}
/**
* Returns the resolver used for the variable of the specified name.
*
* <p>This method does not return <code>null</code>. If the specified variable name is no bound
* to any resolver the default resolver if returned instead.
*
* @param name The name of the variables.
*
* @return the corresponding resolver.
*/
public VariableResolver getResolver(String name) {
VariableResolver resolver = this._byname.get(name);
return resolver != null ? resolver : DEFAULT_RESOLVER;
}
/**
* Returns the resolver used for the variable of the specified type.
*
* <p>This method does not return <code>null</code>. If the specified variable name is no bound
* to any resolver the default resolver if returned instead.
*
* @param type The type of the variable.
*
* @return the corresponding resolver.
*/
public VariableResolver getResolver(VariableType type) {
if (type == null) {
return DEFAULT_RESOLVER;
}
VariableResolver resolver = this._bytype.get(type.getName());
return resolver != null ? resolver : DEFAULT_RESOLVER;
}
/**
* Indicates whether the given variable name is bound to a VariableResolver.
*
* @param name The variable name.
*
* @return <code>true</code> if a given variable resolver is bound to the specific name;
* <code>false</code> otherwise (including if the name is <code>null</code>.
*/
public boolean isNameBound(String name) {
if (name == null) {
return false;
}
return this._byname.containsKey(name);
}
/**
* Indicates whether the given variable type is bound to a VariableResolver.
*
* @param type The variable type.
*
* @return <code>true</code> if a given variable resolver is bound to the specific type;
* <code>false</code> otherwise (including if the type is <code>null</code>.
*/
public boolean isTypeBound(String type) {
if (type == null) {
return false;
}
return this._bytype.containsKey(type);
}
}