You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Sebastian Hennebrueder <us...@laliluna.de> on 2009/08/11 22:23:18 UTC

Possible bug in Hidden component

Hello,

an empty hidden field is not properly decoded. If foo is null, I get
Caused by: java.lang.RuntimeException: Coercion of  to type 
java.lang.Integer (via String --> Long, Long --> Integer) failed: For 
input string: ""
    at 
org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl$TargetCoercion.coerce(TypeCoercerImpl.java:69)
    at 
org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:133)
    at $TypeCoercer_1230b108ecc.coerce($TypeCoercer_1230b108ecc.java)
    at 
org.apache.tapestry5.internal.services.TypeCoercedValueEncoderFactory$1.toValue(TypeCoercedValueEncoderFactory.java:45)
    at 
org.apache.tapestry5.corelib.components.Hidden.processSubmission(Hidden.java:109)
    a

Here is the sample form I used.

Could someone confirm that this is a bug or not?

<t:form>
    <t:hidden t:id="foo" value="foo"/>
    <t:submit/>
</t:form>

public class Sample {
    @Property
    private Integer foo;

    Object onSuccess(){
        System.out.println(foo);
        return null;
    }
}

-- 
Best Regards / Viele Grüße

Sebastian Hennebrueder
-----
Software Developer and Trainer for Hibernate / Java Persistence
http://www.laliluna.de




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Possible bug in Hidden component

Posted by Sebastian Hennebrueder <us...@laliluna.de>.
Hidden fields do not support input validation as well. Shouldn't the 
implementation extend AbstractField?

I put together snippets from the existing Hidden field and the 
AbstractTextField which works for me now. I don't oversee all the 
elements so this is just a raw idea. I am not sure, if we shouldn't 
allow validation for hidden fields.

public class Hidden extends AbstractField{

	/**
	 * The value to read (when rendering) or update (when the form is 
submitted).
	 */
	@Parameter(required = true, autoconnect = true, principal = true)
	private Object value;

	/**
	 * Value encoder for the value, usually determined automatically from 
the type of the property bound to the value
	 * parameter.
	 */
	@Parameter(required = true)
	private ValueEncoder encoder;

	private String controlName;

	@Inject
	private Request request;

	@Inject
	private FieldValidationSupport fieldValidationSupport;
	@Inject
	private ComponentResources resources;
	/**
	 * The object which will perform translation between server-side and 
client-side representations. If not specified,
	 * a value will usually be generated based on the type of the value 
parameter.
	 */
	@Parameter(required = true, allowNull = false, defaultPrefix = 
BindingConstants.TRANSLATE)
	private FieldTranslator<Object> translate;

	/**
	 * The object that will perform input validation (which occurs after 
translation). The validate binding prefix is
	 * generally used to provide this object in a declarative fashion.
	 */
	@Parameter(defaultPrefix = BindingConstants.VALIDATE)
	@SuppressWarnings("unchecked")
	private FieldValidator<Object> validate;

	/**
	 * Defines how nulls on the server side, or sent from the client side, 
are treated. The selected strategy may
	 * replace the nulls with some other value. The default strategy leaves 
nulls alone.  Another built-in strategy,
	 * zero, replaces nulls with the value 0.
	 */
	@Parameter(defaultPrefix = BindingConstants.NULLFIELDSTRATEGY, value = 
"default")
	private NullFieldStrategy nulls;

	@Environmental(false)
	private FormSupport formSupport;

	@Environmental
	private ValidationTracker tracker;

	@Inject
	private ComponentDefaultProvider defaultProvider;

	ValueEncoder defaultEncoder() {
		return defaultProvider.defaultValueEncoder("value", resources);
	}

	final Binding defaultTranslate() {
		return defaultProvider.defaultTranslatorBinding("value", resources);
	}


	/**
	 * Computes a default value for the "validate" parameter using {@link 
org.apache.tapestry5.services.FieldValidatorDefaultSource}.
	 */
	final Binding defaultValidate() {
		return defaultProvider.defaultValidatorBinding("value", resources);
	}

	/**
	 * The default value is a property of the container whose name matches 
the component's id. May return null if the
	 * container does not have a matching property.
	 *
	 * @deprecated Likely to be removed in the future, use {@link 
org.apache.tapestry5.annotations.Parameter#autoconnect()}
	 *             instead
	 */
	final Binding defaultValue() {
		return createDefaultParameterBinding("value");
	}

	static class ProcessSubmission implements ComponentAction<Hidden> {
		private final String controlName;

		public ProcessSubmission(String controlName) {
			this.controlName = controlName;
		}

		public void execute(Hidden component) {
			component.processSubmission(controlName);
		}
	}

	boolean beginRender(MarkupWriter writer) {
		if (formSupport == null)
			throw new RuntimeException("The Hidden component must be enclosed by 
a Form component.");

		controlName = formSupport.allocateControlName(resources.getId());

		formSupport.store(this, new ProcessSubmission(controlName));

		String encoded = encoder.toClient(value);

		writer.element("input",
				"type", "hidden",
				"name", controlName,
				"value", encoded);
		writer.end();

		return false;
	}

	protected void processSubmission(String elementName) {
		String rawValue = request.getParameter(elementName);


		try {
			Object translated = fieldValidationSupport.parseClient(rawValue, 
resources, translate, nulls);

			fieldValidationSupport.validate(translated, resources, validate);

			if (!(InternalUtils.isBlank(rawValue)))
				value = translated;
		}
		catch (ValidationException ex) {
			tracker.recordError(ex.getMessage());
		}
	}
}


Sebastian Hennebrueder schrieb:
> Hello,
> 
> an empty hidden field is not properly decoded. If foo is null, I get
> Caused by: java.lang.RuntimeException: Coercion of  to type 
> java.lang.Integer (via String --> Long, Long --> Integer) failed: For 
> input string: ""
>    at 
> org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl$TargetCoercion.coerce(TypeCoercerImpl.java:69) 
> 
>    at 
> org.apache.tapestry5.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:133) 
> 
>    at $TypeCoercer_1230b108ecc.coerce($TypeCoercer_1230b108ecc.java)
>    at 
> org.apache.tapestry5.internal.services.TypeCoercedValueEncoderFactory$1.toValue(TypeCoercedValueEncoderFactory.java:45) 
> 
>    at 
> org.apache.tapestry5.corelib.components.Hidden.processSubmission(Hidden.java:109) 
> 
>    a
> 
> Here is the sample form I used.
> 
> Could someone confirm that this is a bug or not?
> 
> <t:form>
>    <t:hidden t:id="foo" value="foo"/>
>    <t:submit/>
> </t:form>
> 
> public class Sample {
>    @Property
>    private Integer foo;
> 
>    Object onSuccess(){
>        System.out.println(foo);
>        return null;
>    }
> }
> 



-- 
Best Regards / Viele Grüße

Sebastian Hennebrueder
-----
Software Developer and Trainer for Hibernate / Java Persistence
http://www.laliluna.de



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org