Package play.data
Class Form<T>
java.lang.Object
play.data.Form<T>
- Direct Known Subclasses:
DynamicForm
Helper to manage HTML form description, submission and validation.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic @interfaceDefines a form element's display name.static classA form field. -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionForm(Class<T> clazz, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm.Form(String rootName, Class<T> clazz, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang, boolean directFieldAccess) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang, boolean directFieldAccess) Creates a newForm.Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Form(String rootName, Class<T> clazz, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Method Summary
Modifier and TypeMethodDescriptionRetrieves a field.Retrieves a field.bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, long maxChars, int maxDepth, String... allowedFields) Binds Json data to this form - that is, handles form submission.bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, long maxChars, String... allowedFields) Binds Json data to this form - that is, handles form submission.bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, String... allowedFields) Deprecated.Deprecated as of 2.8.3.Binds data to this form - that is, handles form submission.bind(Lang lang, TypedMap attrs, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, String... allowedFields) Binds data to this form - that is, handles form submission.bindFromRequest(Http.Request request, String... allowedFields) Binds request data to this form - that is, handles form submission.bindFromRequestData(Lang lang, TypedMap attrs, Map<String, String[]> requestData, String... allowedFields) Binds request data to this form - that is, handles form submission.bindFromRequestData(Lang lang, TypedMap attrs, Map<String, String[]> requestData, Map<String, Http.MultipartFormData.FilePart<?>> requestFileData, String... allowedFields) Binds request data to this form - that is, handles form submission.protected Terrors()Returns all errors.com.fasterxml.jackson.databind.JsonNodecom.fasterxml.jackson.databind.JsonNodeerrorsAsJson(Lang lang) Returns the form errors serialized as Json using the given Lang.Retrieves a field.Retrieves a field.files()Populates this form with an existing value, used for edit forms.protected <T> voidprotected voidget()Gets the concrete value only if the submission was a success.Gets the concrete value only if the submission was a success.protected Object[]getArgumentsForConstraint(String objectName, String field, jakarta.validation.ConstraintViolation<Object> violation) protected StringgetMessageForConstraintViolation(jakarta.validation.ConstraintViolation<Object> violation) When dealing with @ValidateWith or @ValidatePayloadWith annotations, and message parameter is not used in the annotation, extract the message from validator's getErrorMessageKey() methodRetrieves the first global error (an error without any key), if it exists.Retrieve all global errors - errors without a key.booleanbooleanlang()protected longThe default maximum number of chars to support when binding a form from JSON.protected intThe default maximum depth of JSON objects and arrays when binding a form from JSON.name()rawData()requestData(Http.Request request) protected Map<String,Http.MultipartFormData.FilePart<?>> requestFileData(Http.Request request) protected <A> Map<String,Http.MultipartFormData.FilePart<?>> resolveDuplicateFilePartKeys(List<Http.MultipartFormData.FilePart<A>> fileParts) toString()value()withDirectFieldAccess(boolean directFieldAccess) Sets if during binding fields of the form should be accessed directly or via getters.withError(ValidationError error) withGlobalError(String error) withGlobalError(String error, List<Object> args) A copy of this form with the given lang set which is used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson().
-
Field Details
-
logger
protected final org.slf4j.Logger logger
-
-
Constructor Details
-
Form
public Form(Class<T> clazz, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
clazz- wrapped classmessagesApi- messagesApi component.formatters- formatters component.validatorFactory- validatorFactory component.config- config component.
-
Form
public Form(String rootName, Class<T> clazz, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?> group, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) -
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)errors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.
-
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)files- the current form file dataerrors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.
-
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)errors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.lang- used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson()
-
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)files- the current form file dataerrors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.lang- used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson()
-
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang, boolean directFieldAccess) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)errors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.lang- used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson()directFieldAccess- access fields of form directly during binding instead of using getters
-
Form
public Form(String rootName, Class<T> clazz, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, List<ValidationError> errors, Optional<T> value, Class<?>[] groups, MessagesApi messagesApi, Formatters formatters, jakarta.validation.ValidatorFactory validatorFactory, com.typesafe.config.Config config, Lang lang, boolean directFieldAccess) Creates a newForm. Consider using aFormFactoryrather than this constructor.- Parameters:
rootName- the root name.clazz- wrapped classdata- the current form data (used to display the form)files- the current form file dataerrors- the collection of errors associated with this formvalue- optional concrete value of typeTif the form submission was successfulgroups- the array of classes with the groups.messagesApi- needed to look up various messagesformatters- used for parsing and printing form fieldsvalidatorFactory- the validatorFactory component.config- the config component.lang- used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson()directFieldAccess- access fields of form directly during binding instead of using getters
-
-
Method Details
-
getBackedType
-
blankInstance
-
maxJsonChars
protected long maxJsonChars()The default maximum number of chars to support when binding a form from JSON. -
maxJsonDepth
protected int maxJsonDepth()The default maximum depth of JSON objects and arrays when binding a form from JSON. -
requestData
-
fillDataWith
-
requestFileData
-
resolveDuplicateFilePartKeys
protected <A> Map<String,Http.MultipartFormData.FilePart<?>> resolveDuplicateFilePartKeys(List<Http.MultipartFormData.FilePart<A>> fileParts) -
fillDataWith
-
bindFromRequest
Binds request data to this form - that is, handles form submission.- Parameters:
request- the request to bind data from.allowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bindFromRequestData
public Form<T> bindFromRequestData(Lang lang, TypedMap attrs, Map<String, String[]> requestData, String... allowedFields) Binds request data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloadrequestData- the map of data to bind fromallowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bindFromRequestData
public Form<T> bindFromRequestData(Lang lang, TypedMap attrs, Map<String, String[]> requestData, Map<String, Http.MultipartFormData.FilePart<?>> requestFileData, String... allowedFields) Binds request data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloadrequestData- the map of data to bind fromrequestFileData- the map of file data to bind fromallowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bind
@Deprecated public Form<T> bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, String... allowedFields) Deprecated.Deprecated as of 2.8.3. Usebind(Lang, TypedMap, JsonNode, long, String...)instead to specify the maximum chars that should be consumed by the flattened form representation of the JSON.Binds Json data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloaddata- data to submitallowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bind
public Form<T> bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, long maxChars, String... allowedFields) Binds Json data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloaddata- data to submitmaxChars- the maximum number of chars allowed to be used in the intermediate map representation of the JSON. `parse.DefaultMaxTextLength` is recommended to passed for this parameter.allowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bind
public Form<T> bind(Lang lang, TypedMap attrs, com.fasterxml.jackson.databind.JsonNode data, long maxChars, int maxDepth, String... allowedFields) Binds Json data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloaddata- data to submitmaxChars- the maximum number of chars allowed to be used in the intermediate map representation of the JSON. `parse.DefaultMaxTextLength` is recommended to passed for this parameter.maxDepth- the maximum depth allowed for JSON objects and arrays.allowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
getArgumentsForConstraint
-
getMessageForConstraintViolation
protected String getMessageForConstraintViolation(jakarta.validation.ConstraintViolation<Object> violation) When dealing with @ValidateWith or @ValidatePayloadWith annotations, and message parameter is not used in the annotation, extract the message from validator's getErrorMessageKey() method- Parameters:
violation- the constraint violation.- Returns:
- the message associated with the constraint violation.
-
bind
Binds data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloaddata- data to submitallowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
bind
public Form<T> bind(Lang lang, TypedMap attrs, Map<String, String> data, Map<String, Http.MultipartFormData.FilePart<?>> files, String... allowedFields) Binds data to this form - that is, handles form submission.- Parameters:
lang- used for validators and formatters during binding and is part ofConstraints.ValidationPayload. Later also used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).attrs- will be passed to validators viaConstraints.ValidationPayloaddata- data to submitallowedFields- the fields that should be bound to the form, all fields if not specified.- Returns:
- a copy of this form filled with the new data
-
rawData
- Returns:
- the actual form data as unmodifiable map. Does not contain file data, use
files()to access files.
-
files
- Returns:
- the the files as unmodifiable map. Use
rawData()to access other form data.
-
name
-
value
- Returns:
- the actual form value - even when the form contains validation errors.
-
fill
Populates this form with an existing value, used for edit forms.- Parameters:
value- existing value of typeTused to fill this form- Returns:
- a copy of this form filled with the new data
-
hasErrors
public boolean hasErrors()- Returns:
trueif there are any errors related to this form.
-
hasGlobalErrors
public boolean hasGlobalErrors()- Returns:
trueif there any global errors related to this form.
-
globalErrors
Retrieve all global errors - errors without a key.- Returns:
- All global errors.
-
globalError
Retrieves the first global error (an error without any key), if it exists.- Returns:
- An error.
-
errors
Returns all errors.- Returns:
- All errors associated with this form.
-
errors
- Parameters:
key- the field name associated with the error.- Returns:
- All errors for this key.
-
error
- Parameters:
key- the field name associated with the error.- Returns:
- an error by key
-
errorsAsJson
public com.fasterxml.jackson.databind.JsonNode errorsAsJson()- Returns:
- the form errors serialized as Json.
-
errorsAsJson
Returns the form errors serialized as Json using the given Lang.- Parameters:
lang- the language to use.- Returns:
- the JSON node containing the errors.
-
get
Gets the concrete value only if the submission was a success. If the form is invalid because of validation errors this method will throw an exception. If you want to retrieve the value even when the form is invalid usevalue()instead.- Returns:
- the concrete value.
- Throws:
IllegalStateException- if there are errors binding the form, including the errors as JSON in the message
-
get
Gets the concrete value only if the submission was a success. If the form is invalid because of validation errors this method will throw an exception. If you want to retrieve the value even when the form is invalid usevalue()instead.- Parameters:
lang- if an IllegalStateException gets thrown it's used to translate the form errors within that exception- Returns:
- the concrete value.
- Throws:
IllegalStateException- if there are errors binding the form, including the errors as JSON in the message
-
withError
- Parameters:
error- theValidationErrorto add to the returned form.- Returns:
- a copy of this form with the given error added.
-
withError
- Parameters:
key- the error keyerror- the error messageargs- the error arguments- Returns:
- a copy of this form with the given error added.
-
withError
- Parameters:
key- the error keyerror- the error message- Returns:
- a copy of this form with the given error added.
-
withGlobalError
- Parameters:
error- the global error messageargs- the global error arguments- Returns:
- a copy of this form with the given global error added.
-
withGlobalError
- Parameters:
error- the global error message- Returns:
- a copy of this form with the given global error added.
-
discardingErrors
- Returns:
- a copy of this form but with the errors discarded.
-
apply
Retrieves a field.- Parameters:
key- field name- Returns:
- the field (even if the field does not exist you get a field)
-
apply
Retrieves a field.- Parameters:
key- field namelang- the language to use for the formatter- Returns:
- the field (even if the field does not exist you get a field)
-
field
Retrieves a field.- Parameters:
key- field name- Returns:
- the field (even if the field does not exist you get a field)
-
field
Retrieves a field.- Parameters:
key- field namelang- used for formatting- Returns:
- the field (even if the field does not exist you get a field)
-
lang
- Returns:
- the lang used for formatting when retrieving a field (via
field(String)orapply(String)) and for translations inerrorsAsJson(). For these methods the lang can be change viawithLang(Lang).
-
withLang
A copy of this form with the given lang set which is used for formatting when retrieving a field (viafield(String)orapply(String)) and for translations inerrorsAsJson(). -
withDirectFieldAccess
Sets if during binding fields of the form should be accessed directly or via getters.- Parameters:
directFieldAccess-trueenables direct field access during form binding,falsedisables it and uses getters instead. Ifnullfalls back to config default.
-
toString
-