blob: 4b13b2cef99d490f45652f45ff79a6d543cb6fed [file] [log] [blame]
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.binding;
import java.util.HashMap;
import java.util.Map;
import org.apache.tapestry.BindingException;
import org.apache.tapestry.IBinding;
import org.apache.tapestry.ILocation;
import org.apache.tapestry.Tapestry;
/**
* Base class for {@link IBinding} implementations.
*
* @author Howard Lewis Ship
* @version $Id$
*
**/
public abstract class AbstractBinding implements IBinding
{
/** @since 3.0 **/
private ILocation _location;
/**
* A mapping from primitive types to wrapper types.
*
**/
private static final Map PRIMITIVE_TYPES = new HashMap();
static {
PRIMITIVE_TYPES.put(boolean.class, Boolean.class);
PRIMITIVE_TYPES.put(byte.class, Byte.class);
PRIMITIVE_TYPES.put(char.class, Character.class);
PRIMITIVE_TYPES.put(short.class, Short.class);
PRIMITIVE_TYPES.put(int.class, Integer.class);
PRIMITIVE_TYPES.put(long.class, Long.class);
PRIMITIVE_TYPES.put(float.class, Float.class);
PRIMITIVE_TYPES.put(double.class, Double.class);
}
/** @since 3.0 **/
protected AbstractBinding(ILocation location)
{
_location = location;
}
public ILocation getLocation()
{
return _location;
}
/**
* Cooerces the raw value into a true or false, according to the
* rules set by {@link Tapestry#evaluateBoolean(Object)}.
*
**/
public boolean getBoolean()
{
return Tapestry.evaluateBoolean(getObject());
}
public int getInt()
{
Object raw;
raw = getObject();
if (raw == null)
throw Tapestry.createNullBindingException(this);
if (raw instanceof Number)
{
return ((Number) raw).intValue();
}
if (raw instanceof Boolean)
{
return ((Boolean) raw).booleanValue() ? 1 : 0;
}
// Save parsing for last. This may also throw a number format exception.
return Integer.parseInt((String) raw);
}
public double getDouble()
{
Object raw;
raw = getObject();
if (raw == null)
throw Tapestry.createNullBindingException(this);
if (raw instanceof Number)
{
return ((Number) raw).doubleValue();
}
if (raw instanceof Boolean)
{
return ((Boolean) raw).booleanValue() ? 1 : 0;
}
// Save parsing for last. This may also throw a number format exception.
return Double.parseDouble((String) raw);
}
/**
* Gets the value for the binding. If null, returns null,
* otherwise, returns the String (<code>toString()</code>) version of
* the value.
*
**/
public String getString()
{
Object value;
value = getObject();
if (value == null)
return null;
return value.toString();
}
/**
* @throws BindingException always.
*
**/
public void setBoolean(boolean value)
{
throw createReadOnlyBindingException(this);
}
/**
* @throws BindingException always.
*
**/
public void setInt(int value)
{
throw createReadOnlyBindingException(this);
}
/**
* @throws BindingException always.
*
**/
public void setDouble(double value)
{
throw createReadOnlyBindingException(this);
}
/**
* @throws BindingException always.
*
**/
public void setString(String value)
{
throw createReadOnlyBindingException(this);
}
/**
* @throws BindingException always.
*
**/
public void setObject(Object value)
{
throw createReadOnlyBindingException(this);
}
/**
* Default implementation: returns true.
*
* @since 2.0.3
*
**/
public boolean isInvariant()
{
return true;
}
public Object getObject(String parameterName, Class type)
{
Object result = getObject();
if (result == null)
return result;
Class resultClass = result.getClass();
if (type.isAssignableFrom(resultClass))
return result;
if (type.isPrimitive() && isWrapper(type, resultClass))
return result;
String key =
type.isInterface() ? "AbstractBinding.wrong-interface" : "AbstractBinding.wrong-type";
String message =
Tapestry.format(
key,
new Object[] { parameterName, result, resultClass.getName(), type.getName()});
throw new BindingException(message, this);
}
public boolean isWrapper(Class primitiveType, Class subjectClass)
{
return PRIMITIVE_TYPES.get(primitiveType).equals(subjectClass);
}
/** @since 3.0 **/
protected BindingException createReadOnlyBindingException(IBinding binding)
{
return new BindingException(
Tapestry.getMessage("AbstractBinding.read-only-binding"),
binding);
}
}