I want to store phone numbers in Grails domain classes. I am not sure what is the best way of doing this. Storing as int does not seems to be a good idea because leading zero is impossible for that.
What is the best way to store and validate phone numbers in Grails domain classes?
I would store phone as a String - nullable and blank too. For display purposes, simply provide your own tag in grails's tablib package.
For example, with a property inside some domain class like this:
String phone
And a taglib class like this:
class MyTagLib {
static defaultEncodeAs = [taglib:'html']
def phone334 = { attrs ->
String phone = attrs.phone
def formatted =
"(".concat(phone.substring(0, 3)).concat(") ")
.concat(phone.substring(3, 6)).concat("-").concat(phone.substring(6))
out << formatted
}
}
and a usage like this inside a gsp:
<g:phone334 phone="${theInstance.phone}" />
Then if phone = '4165557799', the output would be displayed like this: (416) 555-7799.
You can build as many formatters as you want; for example, if your number is 011218213334488 and you need it to look like +(218) 21 333 4488, simply build a formatter for that depending on the length and/or the pattern detected in the input.
You can also build simple validators right there too to make sure for example that all characters are made up of digits and parentheses and dashes, but I don't think taglibs are the right place for that - perform a bit of filtering and validation as suggested in the other posts before getting to displaying what should be correct input material.
You could most probably use matches constraint and store phone numbers as String as there is no predefined constraints for phone numbers. There in matches you can use any regex pattern required according to your needs.
static constraints = {
phone(matches: "^(?:0091|\\+91|0)[7-9][0-9]{9}$")
}
The above regex will work like :-
Begins with 0, +91 or 0091
Followed by a 7-9
Followed by exactly 9 numbers
Must match entire input
You can change it according to your needs.
You can store the phone number as string. To validate the phone number you can use google phone number java library to validate international numbers. Or more easily you can use this grails plugin in your code: https://github.com/ataylor284/grails-phonenumbers . Here is a sample from the plugin home page.
class MyDomain {
String phoneNumber
static constraints = {
phoneNumber(phoneNumber: true)
}
}
Edit:
To validate the number if it is not blank you have to define your custom constraint class which extends PhoneNumberConstraint class.
class CustomPhoneNumberConstraint extends PhoneNumberConstraint{
#Override
protected void processValidate(target, propertyValue, Errors errors) {
//check if phone number is blank
if (propertyValue instanceof String && GrailsStringUtils.isBlank((String)propertyValue)) {
if (!blank) {
super.processValidate(target,propertyValue, errors)
}
}
return true
}
}
Related
Is there any way of storing line numbers in the created parse tree, using ANTLR 4? I came across this article, which does it but I think it's for older ANTLR version, because
parser.setASTFactory(factory);
It does not seem to be applicable to ANTLR 4.
I am thinking of having something like
treenode.getLine()
, like we can have
treenode.getChild()
With Antlr4, you normally implement either a listener or a visitor.
Both give you a context where you find the location of the tokens.
For example (with a visitor), I want to keep the location of an assignment defined by a Uppercase identifier (UCASE_ID in my token definition).
The bit you're interested in is ...
ctx.UCASE_ID().getSymbol().getLine()
The visitor looks like ...
static class TypeAssignmentVisitor extends ASNBaseVisitor<TypeAssignment> {
#Override
public TypeAssignment visitTypeAssignment(TypeAssignmentContext ctx) {
String reference = ctx.UCASE_ID().getText();
int line = ctx.UCASE_ID().getSymbol().getLine();
int column = ctx.UCASE_ID().getSymbol().getCharPositionInLine()+1;
Type type = ctx.type().accept(new TypeVisitor());
TypeAssignment typeAssignment = new TypeAssignment();
typeAssignment.setReference(reference);
typeAssignment.setReferenceToken(new Token(ctx.UCASE_ID().getSymbol().getLine(), ctx.UCASE_ID().getSymbol().getCharPositionInLine()+1));
typeAssignment.setType(type);
return typeAssignment;
}
}
I was new to Antlr4 and found this useful to get started with listeners and visitors ...
https://github.com/JakubDziworski/AntlrListenerVisitorComparison/
I had one custom parser rule in which I had defined all my keywords such as _self, _for, _loop etc. Because of this, if I type _s and click Ctrl+ space bar, it shows _self.But what I required is even though I type self or SE, it should auto assign as _self.Is it possible? If so, could anyone please suggest a solution for this. Thanks in advance
There are multiple things to be payed attention to
There needs to be a proposal and only one proposal. Otherwise the user has to select the prosal to be applied and no auto insert takes places
Proposals are created based on the error recovery and so you might not get the proposal you are looking for at all
so lets assume you have a grammar like
Model:
greetings+=Greeting*;
Greeting:
'_self' name=ID '!';
and a model file like
SE
Then the error recovery will work fine an a proposal of "_self" will be added to the list of proposals
Proposals are Filtered based on the current prefix in the model. that would be the place you could start customizing.
e.g. this very naive impl
import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher;
public class MyPrefixMatcher extends FQNPrefixMatcher {
#Override
public boolean isCandidateMatchingPrefix(String name, String prefix) {
return super.isCandidateMatchingPrefix(name, prefix) || super.isCandidateMatchingPrefix(name, "_" + prefix);
}
}
and dont forget to bind
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher
import org.xtext.example.mydsl4.ui.contentassist.MyPrefixMatcher
#FinalFieldsConstructor
class MyDslUiModule extends AbstractMyDslUiModule {
override Class<? extends PrefixMatcher> bindPrefixMatcher() {
return MyPrefixMatcher;
}
}
There is another feature that does not use proposals at all but the text that is actually typed and if it recognizes something then can replace it with something else. this feature is called "Auto Edit". The extension point in xtext for this is IAutoEditStrategy / AbstractEditStrategyProvider
I'm not a programming savvy person, so please bear with me.
I've read blog entries and docs about command object. I've never used it and was wondering if I should. (I probably should...)
My project requires parsing, sorting, calculating, and saving results into database when users upload files.
So according to one of the blog entries I read and its corresponding github code,
1) SERVICE should receive file uploads, parse uploaded files (mainly docs and pdfs), sort parsed data using RegEx, and calculate data,
2) COMMAND OBJECT should call SERVICE, collect results and send results back to controller, and save results into the database,
3) CONTROLLER should receive request from VIEW, get results from COMMAND OBJECT, and send results back to VIEW.
Did I understand correctly?
Thanks.
I found this to be the best setup. Here is an example that I use on production:
Command Object (to carry data and ensure their validity):
#grails.validation.Validateable
class SearchCommand implements Serializable {
// search query
String s
// page
Integer page
static constraints = {
s nullable: true
page nullable: true
}
}
Controller (directs a request to a Service and then gets a response back from the Service and directs this response to a view):
class SomeController {
//inject service
def someService
def search(SearchCommand cmd) {
def result = someService.search(cmd)
// can access result in .gsp as ${result} or in other forms
render(view: "someView", model: [result: result])
}
}
Service (handles business logic and grabs data from Domain(s)):
class SomeService {
def search(SearchCommand cmd) {
if(cmd.hasErrors()) {
// errors found in cmd.errors
return
}
// do some logic for example calc offset from cmd.page
def result = Stuff.searchAll(cmd.s, offset, max)
return result
}
}
Domain (all database queries are handled here):
class Stuff {
String name
static constraints = {
name nullable: false, blank: false, size: 1..30
}
static searchAll(String searchQuery, int offset, int max) {
return Stuff.executeQuery("select s.name from Stuff s where s.name = :searchQuery ", [searchQuery: searchQuery, offset: offset, max:max])
}
}
Yes, you understood it correctly except the one thing: command object shouldn't save the data to DB - let service to do that. The other advantage of command object is data binding and validation of data from the client. Read more about command objects here grails command object docs
You can also find helpful information regarding your question in this article
grails best practices
I guess not. Its not really related to whether the save is done in a service it should always attempt to carry out complex stuff and specifically db stuff in a service. so that is regardless. I tend to not use command object but have got hooked on helper classes aka beans that sit in src/main/groovy and do all of the validation and formatting. I just did a form and in it has feedback and reason.
Initially I thought I would get away with
def someAction(String feedback, String reason) {
someService.doSomething(feedback,reason)
}
But then I looked closed and my form was firstly a textarea then the selection objects were bytes so above was not working and to simply fix it without adding the complexity to my controller/service I did this:
packe some.package
import grails.validation.Validateable
class SomeBean implements Validateable {
User user
byte reason
String feedback
static constraints = {
user(nullable: true)
reason(nullable:true, inList:UsersRemoved.REASONS)
feedback(nullable:true)
}
void setReason(String t) {
reason=t as byte
}
void setFeedback(String t) {
feedback=t?.trim()
}
}
Now my controller
class SomeController {
def userService
def someService
def doSomething(SomeBean bean){
bean.user = userService.currentUser
if (!bean.validate()) {
flash.message=bean.errors.allErrors.collect{g.message([error : it])}
render view: '/someTemplate', model: [instance: bean,template:'/some/template']
return
}
someService.doSomeThing(bean)
}
}
Now my service
Class SomeService {
def doSomeThing(SomeBean bean) {
if (bean.user=='A') {
.....
}
}
All of that validation would have still had to have been done somewhere, you say no validation but in a good model you should do validation and set things to be stored in proper structures to reduce overloading your db over time. difficult to explain but in short i am talking about your domain class objects and ensuring you are not setting up String something string somethingelse and then not even defining their lenghts etc. be strict and validate
if you have a text area this will be stored in the back end - so you will need to trim it like above - you will need to ensure the input does not exceed the max character of the actual db structure which if not defined will probably be 255
and by doing
static constraints = {
user(nullable: true)
reason(min:1, max:255, nullable:true, inList:UsersRemoved.REASONS)
Has already invalidated it through the bean.validate() in the controller if the user exceeded somehow my front end checks and put in more than 255.
This stuff takes time be patient
Edited to finally add in that example byte - is one to be careful of -
When adding any String or what ever I have started to define the specific like this and in the case of byte if it is a boolean true false - fine if not then define it as a tinyint
static mapping = {
//since there is more than 1 type in this case
reason(sqlType:'tinyint(1)')
feedback(sqlType:'varchar(1000)')
// name(sqlType:'varchar(70)')
}
If you then look at your tables created in the db you should find they have been created as per definition rather than standard 255 varchar which I think is the default for a declared String.
Requirements
I want to check password policies by using multiple regex expressions.
For each policy violation I want to display a specific validation message.
Examples:
You need to use at least 2 numbers
You need to use at least one upper and one lower case letter
You need to use at least 8 letters
...
Attempt
I tried to use multiple regex expressions (Fluent Validation Match(string expression)), but ASP.NET MVC does not allow to have multiple regex expressions.
The following validation type was seen more than once: regex
Question
How can I use multiple regex validators in Fluent Validation?
You can use custom method defined in Abstract validator:
public class UserValidator : AbstractValidator<User> {
public UserValidator () {
Custom(user => {
Regex r1 = define regex that validates that there are at least 2 numbers
Regex r2 = define regex for upper and lower case letters
string message = string.Empty;
if(!r1.IsMatch(user.password))
{
message += "You need to use at least 2 numbers.";
}
if(!r2.IsMatch(user.password))
{
message += "You need to use at least one upper and one lower case letter.";
}
return message != string.Empty;
? new ValidationFailure("Password", message )
: null;
});
}
}
I am using an older version of grails (1.1.1) and I am working on a legacy application for a government client.
Here is my question (in psuedo form):
I have a domain that is a Book. It has a sub domain of type Author associated with it (1:many relationship). The Author domain has a firstName and lastName field.
def c = Book.createCriteria()
def booklist = c.listDistinct {
author {
order('lastName', 'asc')
order('firstName', 'asc')
}
}
Let's say I have a list of fields I want to use for an excel export later. This list has both the author domain call and the title of the column I want to use.
Map fields = ['author.lastName' : 'Last Name', 'author.firstName', 'First Name']
How can I dynamically call the following code--
booklist.eachWithIndex(){
key, value ->
println key.fields
}
The intent is that I can create my Map of fields and use a loop to display all data quickly without having to type all of the fields by hand.
Note - The period in the string 'author.lastName' throws an error when trying to output key['author.lastName'] too.
I don't recall the version of Groovy that came with Grails 1.1, but there are a number of language constructs to do things like this. If it's an old version, some things may not be available - so your mileage may vary.
Map keys can be referenced with quotes strings, e.g.
def map = [:]
map."person.name" = "Bob"
The above will have a key of person.name in the map.
Maps can contain anything, including mixed types in Groovy - so you really just need to work around string escapes or other special cases if you are using more complex keys.
You can also use a GString in the above
def map = [:]
def prop = "person.name"
map."${prop}" = "Bob"
You can also get a map of property/value off of a class dynamically by the properties field on it. E.g.:
class Person { String name;String location; }
def bob = new Person(name:'Bob', location:'The City')
def properties = bob.properties
properties.each { println it }