blob: feed759241cce96a0277a047de7ab6c32db60231 [file] [log] [blame]
// Copyright 2007, 2008, 2010 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.tapestry5.internal.services;
import org.apache.tapestry5.ComponentEventCallback;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.EventConstants;
import org.apache.tapestry5.FieldTranslator;
import org.apache.tapestry5.FieldValidationSupport;
import org.apache.tapestry5.FieldValidator;
import org.apache.tapestry5.NullFieldStrategy;
import org.apache.tapestry5.ValidationException;
import org.apache.tapestry5.corelib.internal.InternalMessages;
import org.apache.tapestry5.internal.util.Holder;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.ioc.util.ExceptionUtils;
@SuppressWarnings("all")
public class FieldValidationSupportImpl implements FieldValidationSupport
{
private final TypeCoercer typeCoercer;
public FieldValidationSupportImpl(TypeCoercer typeCoercer)
{
this.typeCoercer = typeCoercer;
}
public String toClient(Object value, ComponentResources componentResources, FieldTranslator<Object> translator,
NullFieldStrategy nullFieldStrategy)
{
assert componentResources != null;
assert translator != null;
assert nullFieldStrategy != null;
final Holder<String> resultHolder = Holder.create();
ComponentEventCallback callback = new ComponentEventCallback()
{
public boolean handleResult(Object result)
{
// What's nice is that the ComponentEventException will automatically identify
// the method description.
if (!(result instanceof String))
throw new RuntimeException(InternalMessages.toClientShouldReturnString());
resultHolder.put((String) result);
return true;
}
};
componentResources.triggerEvent(EventConstants.TO_CLIENT, new Object[]
{ value }, callback);
if (resultHolder.hasValue())
return resultHolder.get();
Object effectiveValue = value;
if (effectiveValue == null)
{
effectiveValue = nullFieldStrategy.replaceToClient();
// Don't try to coerce or translate null.
if (effectiveValue == null)
return null;
}
// And now, whether its a value from a bound property, or from the null field strategy,
// get it into the right format for the translator and let it translate.
Object coerced = typeCoercer.coerce(effectiveValue, translator.getType());
return translator.toClient(coerced);
}
public Object parseClient(String clientValue, ComponentResources componentResources,
FieldTranslator<Object> translator, NullFieldStrategy nullFieldStrategy) throws ValidationException
{
assert componentResources != null;
assert translator != null;
assert nullFieldStrategy != null;
String effectiveValue = clientValue;
if (InternalUtils.isBlank(effectiveValue))
{
effectiveValue = nullFieldStrategy.replaceFromClient();
if (effectiveValue == null)
return null;
}
final Holder<Object> resultHolder = Holder.create();
ComponentEventCallback callback = new ComponentEventCallback()
{
public boolean handleResult(Object result)
{
resultHolder.put(result);
return true;
}
};
try
{
componentResources.triggerEvent(EventConstants.PARSE_CLIENT, new Object[]
{ effectiveValue }, callback);
}
catch (RuntimeException ex)
{
rethrowValidationException(ex);
}
if (resultHolder.hasValue())
return resultHolder.get();
return translator.parse(effectiveValue);
}
/**
* Checks for a {@link org.apache.tapestry5.ValidationException} inside the outer exception and throws that,
* otherwise rethrows the runtime exception.
*
* @param outerException
* initially caught exception
* @throws ValidationException
* if found
*/
private void rethrowValidationException(RuntimeException outerException) throws ValidationException
{
ValidationException ve = ExceptionUtils.findCause(outerException, ValidationException.class);
if (ve != null)
throw ve;
throw outerException;
}
@SuppressWarnings(
{ "unchecked" })
public void validate(Object value, ComponentResources componentResources, FieldValidator validator)
throws ValidationException
{
assert componentResources != null;
assert validator != null;
validator.validate(value);
try
{
componentResources.triggerEvent(EventConstants.VALIDATE, new Object[]
{ value }, null);
}
catch (RuntimeException ex)
{
rethrowValidationException(ex);
}
}
}