Play for Scala - more than one .verifying criteria when mapping? - scala

I'm new to both Scala and Play, currently working through Chapter 2 of 'Play for Scala' and have a query about the 'Products' application.
The application features a barcode generator that needs a longNumber value with 11 or 12 characters, but there is no validation in place to check that the longNumber has the correct number of characters. This means that the barcode image does not always generate correctly.
Current verification, provided by the book, is:
private val productForm: Form[Product] = Form(
mapping(
"ean" -> longNumber.verifying(
"validation.ean.duplicate", Product.findByEan(_).isEmpty),
"name" -> nonEmptyText,
"description" -> nonEmptyText
)(Product.apply)(Product.unapply)
)
Is there any way to add another set of 'verifying' criteria to the "ean" value? Ideally to check whether "ean" is long enough, and if not display a "validation.ean.length" message.
Many thanks

Mapping.verifying returns a new Mapping, so you can just call verifying again on it. You can chain as many of these as you like this way.

Related

Can we set tolerance level on regex annotator in Ruta?

I am annotating Borrower Name
"Borrower Name" -> BorrowerNameKeyword ( "label" = "Borrower Name");
But I get this text post OCR analysis. At times I might get Borrower Name as B0rr0wer Nane. Is this possible to set tolerance limit so that this text gets annotated as BorrowerNameKeyword?
Is their any other approach which could help here?
I could think of dictionary correction but that wont help as it could auto correct right words.
You could achieve that with regular expressions in UIMA Ruta. For you particular example the following rule should work:
"B.rr.wer\\sNa.e" -> BorrowerName;
Likewise, you can create more variants of regular expressions to cover the OCR errors.

Setting Features-Uima Ruta

I am trying "learning by example" which was given in the uima ruta documentation.I have tried how to define and assign a relation of employment, by storing the given annotations as feature values.But I got error messages.I'm not clear in that concept can explain me in detail.
DECLARE Annotation EmplRelation
(Employee employeeRef, Employer employerRef);
Sentence{CONTAINS(EmploymentIndicator) -> CREATE(EmplRelation,"employeeRef" = Employee, "employerRef" = Employer)};
e1:Employer # EmploymentIndicator # e2:Employee) {-> EmplRelation, EmplRelation.employeeRef=e2, EmplRelation.employerRef=e1};
Just assuming what the mentioned error messages could be: The script in the question is not complete. The section "learning by example" does not contain always complete scripts but builts upon previous examples. A complete and running script for this example could look like (for an input text like "Peter works for Frank."):
DECLARE Employee, Employer, EmploymentIndicator, Sentence;
DECLARE EmplRelation (Employee employeeRef, Employer employerRef);
// create some dummy annotations to work on
"Peter" -> Employee;
"Frank" -> Employer;
"works for" -> EmploymentIndicator;
(# PERIOD){-> Sentence};
// the actual rules
Sentence{CONTAINS(EmploymentIndicator) -> CREATE(EmplRelation,"employeeRef" = Employee, "employerRef" = Employer)};
(e1:Employee # EmploymentIndicator # e2:Employer) {-> EmplRelation, EmplRelation.employeeRef=e1, EmplRelation.employerRef=e2};
Please mind that I modified the last rule so that it works on the minimal example.
DISCLAIMER: I am a developer of UIMA Ruta

UIMA Ruta: Copy the feature value from a contained annotation to a containing annotation

Note: This seems heavily related to Setting feature value to the count of containing annotation in UIMA Ruta. But I cannot quite apply the answer to my situation.
I am analyzing plain text documents where the following structure is assumed:
Document (one, of course)
Section (many)
Heading (one per section)
I am being asked to identify sections by checking whether their headings satisfy conditions. A useful and obvious sort of condition would be: does the heading match a given regular expression? A less-useful but perhaps more achievable condition would be: does the heading contain a given text?
I could and have already achieved this by taking a list of tuples of regular expressions and section titles, and at design time, for each member of the list, as such:
BLOCK(forEach) SECTION{} {
...
HEADING{REGEXP(".*table.*contents.*", true) ->
SETFEATURE("value", "Table of Contents")};
...
}
SECTION{ -> SETFEATURE("value", "Table of Contents")}
<- { HEADING.headingValue == "Table of Contents"; };
This approach is fairly straightforward but has a few big drawbacks:
It heavily violates the DRY principle
Even when writing the rule for just one section to identify, the rule author must copy the section title twice (it should only need to be specified once)
It makes the script needlessly long and unwieldy
It puts a big burden on the rule author, who in an ideal case, would only need to know Regex - not Ruta
So I wanted to refactor to achieve the following goals:
A text file is used to store the regular expressions and corresponding titles, and the rule iterates over these pairs
Features, rather than types, are used to differentiate different sections/headings (i.e. like above, using SECTION.value=="Table of Contents" and not TableOfContentsSection)
After looking over the UIMA Ruta reference to see which options were available to achieve these goals, I settled on the following:
Use a WORDTABLE to store tuples of section title, words to find / regex if possible, lookup type - so for instance, Table of Contents,contents,sectiontitles
Use MARKTABLE to mark an intermediate annotation type LookupMatch whose hint feature contains the section title and whose lookup feature contains the type of lookup we are talking about
For each HEADING, see if a LookupMatch.lookup == "sectiontitle" is inside, and if it is, copy the LookupMatch.hint to the heading's value field.
For each SECTION, see if a HEADING with a value is inside; if so, copy the value to the SECTION.value field.
It was not quite a surprise to find that implementing steps 3 and 4 was not so easy. That's where I am at and why I am asking for help.
// STEP 1
WORDTABLE Structure_Heading_WordTable =
'/uima/resource/structure/Structure_Heading_WordTable.csv';
// STEP 2
Document.docType == "Contract"{
-> MARKTABLE(LookupMatch, // annotation
2, // lookup column #
Structure_Heading_WordTable, // word table to lookup
true, // case-insensitivity
0, // length before case-insensitivity
"", // characters to ignore
0, // matches to ignore
"hint" = 1, "lookup" = 3 // features
)
};
// STEPS 3 AND 4 ... ???
BLOCK(ForEach) LookupMatch.lookup == "sectiontitle"{} {
???
}
HEADING{ -> SETFEATURE("value", ???)} <- {
???
};
Here is my first real stab at it:
HEADING{ -> SETFEATURE("value", lookupMatchHint)} <- {
LookupMatch.lookup == "HeadingWords"{ -> GETFEATURE("hint", lookupMatchHint)};
};
TL; DR
How can I conditionally copy a feature value from one annotation to another? GETFEATURE kind of assumes that you only get 1...

Dynamic value of textarea with Play framework with Silhouette

There is a need to perform parsing of data from textarea and keep it safe on page update to let it be easily changeable for further experiments.
Before I have added the Silhouette to the app everything was pretty ok.
The page was getting the input parameter:
#(textToParse: String)
and its value was passed to plain HTML tag like:
<textarea ...>#textToParse</textarea>
But when I have added the Silhouette and used the form field construtor, I have met a problem:
#import b3.inline.fieldConstructor
#b3.textarea(someForm("text"), 'rows -> "12", 'value -> "#textToParse")
displays hardcoded "#textToParse" instead of the parameter value.
Skipping the quotes ('value -> #textToParse) leads to compilation error:
Type mismatch: found (Nothing) => (Symbol, Nothing), required (Symbol, Any)
I have checked the documentation on offsite http://silhouette.mohiva.com/docs/ and googled, but with no result.
Any working suggestions will be much appreciated!
Your code must look like:
#b3.textarea(someForm("text"), 'rows -> "12", 'value -> textToParse)
With Twirl, the Play template engine, you start an expression with the # sign. So in your case you start the expression with the Bootstrap 3 form helper. All other which is in the expression must be normal Scala code.

How to suppress the Play framework's output of data types in forms

Using the helper functions of the Play framework to create form elements (particularly text inputs) results in inputs being labeled with "required", "numeric", "real", etc.
I want to suppress the output of all but "required". How can I do this? Is there a per-input way to modify this text?
To demonstrate, here's an example of the text, placed below the input:
Which are created with:
#inputText(
propertyForm("totalRooms"),
'_label -> Messages("properties.add.totalRooms"),
)
They can't trivially be removed with CSS, since the "required" and "numeric" (etc) labels all have the same class (and it'd be ideal to be able to specify what text goes there, rather than completely remove it).
I think you may use internationalization files (the "messages" file) to override them. You may be able to associate an empty String to the key. Some of the keys I use that come form Play are :
# --- Constraints
constraint.required=Obligatoire
constraint.min=Valeur minimum : {0}
constraint.max=Valeur maximum : {0}
constraint.minLength=Longueur minimum : {0}
constraint.maxLength=Longueur maximum : {0}
constraint.email=Email
# --- Formats
format.date=Date (''{0}'')
format.numeric=Numérique
format.real=Réel