Grails MongoDB FindAll does not work for special characters - mongodb

I've been trying to add search functionality to my grails project
Here's my domain class
class Resource {
String mimeType
String resourceUrl
String website
static constraints = {
}
}
and here's my controller
class ResourceController {
def report()
{
def website = params.website
println "inside report " + website
def res = Resource.findAllByWebsite(website)
int noOfResources = res.size()
println noOfResources
}
This code works for values of website without any special characters like www.google.com but for some reason whenever there is any special characters in the website valuelike ? or anything, it doesnt fetch anything from the database. Please suggest me an alternate approach.
I tried this as well: def res = Resource.findAllByWebsiteLike(website) but it didn't work too.

Have you tried using a regex search?
such as :
def searchMap
searchMap.put(fieldSearch, [ '$regex' : website, '$options': 'i'] )
def res = Resource.collection.find(searchMap)

Related

Read password in Scala in a console-agnostic way

I have an easy task to accomplish: read a password from a command line prompt without exposing it. I know that there is java.io.Console.readPassword, however, there are times when you cannot access console as if you are running your app from an IDE (such as IntelliJ).
I stumbled upon this Password Masking in the Java Programming Language tutorial, which looks nice, but I fail to implement it in Scala. So far my solution is:
class EraserThread() extends Runnable {
private var stop = false
override def run(): Unit = {
stop = true
while ( stop ) {
System.out.print("\010*")
try
Thread.sleep(1)
catch {
case ie: InterruptedException =>
ie.printStackTrace()
}
}
}
def stopMasking(): Unit = {
this.stop = false
}
}
val et = new EraserThread()
val mask = new Thread(et)
mask.start()
val password = StdIn.readLine("Password: ")
et.stopMasking()
When I start this snippet I get a continuos printing of asterisks on new lines. E.g.:
*
*
*
*
Is there any specific in Scala why this is not working? Or is there any better way to do this in Scala in general?

Resolve a standalone string/file using typesafe config

I'm looking for a way to say:
val c: Config = ConfigFactory.parseString("a=fox,b=dog")
val s: String = """This is a "quick" brown ${a}.\nThat is a lazy, lazy ${b}."""
println(c.resolveString(s))
// Should print:
// > This is a "quick" brown fox.
// > That is a lazy lazy dog.
My two ideas:
Just find the placeholders with regex and replace from config one by one
convert s to config with single value and use resolveWith - but it seems quoting can be really tricky
Maybe there is an easier way?
A naive solution:
class Resolver(vars: Config) {
private lazy val placeholderRegex = "(?<=\\$\\{).*?(?=\\})".r
def resolveString(s: String): String = {
placeholderRegex.findAllIn(s).foldLeft(s) { (str, v) =>
if (vars.hasPath(v)) str.replaceAll("\\Q${" + v + "}\\E", vars.getString(v)) else str
}
}
It should be fine if the string is not huge and there are no insane numbers of distinct placeholders in it.
I have a similar situation where I automatically push elastic search index definitions before
I launch the job which uses those index definitions.
In my case the string which contains variable references is the
JSON index/template definition, which ALSO comes from the typesafe config.
(see es.template_or_index.json, below.)
I resolve these refs using the utility method I wrote on top
of apache.commons StrSubstitutor.
(see: VariableReferenceResolver.resolveReferences(String template), below)
Below is a sample of my config. Note how the property 'es.animal' is injected into the index/template json.
This can't be done with out-of-the-box features of the typesafe config library (but I think this would
be a wonderful feature for them to add !)
es {
// user and password credentials should not be checked in to git. deployer is expected to
// set these parameters into the their environment in whatever way is convenient -- .bashrc or whatever.
user = dummy
user = ${?ES_USER}
password = dummy.passwd
password = ${?ES_PASSWORD}
hostPort = "localhost:9200"
hostPort = ${?ES_HOST_PORT}
protocol = http
protocol = ${?ES_PROTOCOL}
animal = horse // This gets injected into the configuration property es.template_or_index.json
// Note: for template json there is a second round of interpolation performed so the json can reference any defined
// property of this configuration file (or anything it includes)
template_or_index {
name = test_template
json = """
{
"template": "${es.animal}_sql-*",
"settings": {
"number_of_shards": 50,
"number_of_replicas": 2
},
"mappings": {
"test_results" : {
"date_detection": false,
"properties" : {
"timestamp" : { "type" : "date"},
"yyyymmdd" : { "type" : "string", "index" : "not_analyzed"}
}
}
}
}
"""
}
}
package com.foo
import com.typesafe.config.Config;
import org.apache.commons.lang.text.StrLookup;
import org.apache.commons.lang.text.StrSubstitutor;
public class VariableReferenceResolver {
final StrSubstitutor substitutor;
static class ConfigStrLookup extends StrLookup {
private final Config config;
ConfigStrLookup(Config config) {
this.config = config;
}
public String lookup(String key) {
return config.getString(key);
}
}
public VariableReferenceResolver (Config config) {
substitutor=new StrSubstitutor(new ConfigStrLookup(config));
}
public String resolveReferences(String template) {
return substitutor.replace(template);
}
}
public class OtherClass {
private static void getIndexConfiguration(String path) throws IOException {
System.setProperty("config.file", path);
Config config = ConfigFactory.load();
String user = config.getString("es.user");
String password = config.getString("es.password");
String protocol = config.getString("es.protocol");
String hostPort = config.getString("es.hostPort");
String indexOrTemplateJson = config.getString("es.template_or_index.json");
String indexOrTemplateName = config.getString("es.template_or_index.name");
VariableReferenceResolver resolver = new VariableReferenceResolver(config);
String resolvedIndexOrTemplateJson = resolver.resolveReferences(indexOrTemplateJson);
File jsonFile = File.createTempFile("index-or-template-json", indexOrTemplateName);
Files.write(Paths.get(jsonFile.getAbsolutePath()), resolvedIndexOrTemplateJson.getBytes());
curlIndexOrTemplateCreateCommand =
String.format(
"curl -XPUT -k -u %s:%s %s://%s/_template/%s -d #%s",
user, password, protocol, hostPort, indexOrTemplateName, jsonFile.getAbsolutePath());
}
....
}

grails Objects query when hasMany relationship is NULL

Not able to get the list of Objects when a hasMany attribute is null.
Class User {
...
List<EMail> emails
static hasMany = [emails: EMail,... ]
static mappedBy = [emails: 'customer',...]
...
}
Where Email is another Class with some String Attributes
Now i am trying to make a simple query as:
Method 1:
def users = User.findAllByEmailsIsEmpty()
This is giving Error as:
Queries of type IsEmpty are not supported by this implementation
Method 2:
def users = User.findAllByEmailsIsNull()
This is giving all the users even those have Email object associated with it.
Then I thought of trying Criteria Query (https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/createCriteria.html )
Method 3:
def userCriteria = User.createCriteria()
def users = userCriteria.list(){
sizeEq('emails', 0)
}
This gives No result ( users.size() is 0 )
Method 4:
def userCriteria = User.createCriteria()
def users = userCriteria.list(){
isNull('emails')
}
This again gives all the Users even those who don't have emails.
Method 5:
def userCriteria = User.createCriteria()
def users = userCriteria.list(){
isEmpty('emails')
}
This gives the Error :
Queries of type IsEmpty are not supported by this implementation
Method 6:
def userCriteria = User.createCriteria()
def users = userCriteria.list(){
eq('emails', null)
}
This again lists down all the users.
PS: Grails is configured with Database as MongoDB.
I would use the grep method. Something like this:
nullEmailUsers = User.list().grep {
!it.emails
}
User.findAll { emails.id != null } do the job!

how to get autocomplete text box value using lift web

I am using Lift web framework.
I am implementing an auto-complete text box. When I enter some value in the box a drop-down list opens. If I select a value from that list, only then I am able to access value of text box. If I write a value by myself then I get an empty value.
My code :
var friend_name=""
"#bdayReminder" #> AutoComplete("",
getAllName _,
value => takeAction(value),
List("minChars" -> "3"))
private def takeAction(str: String) {
friend_name = str
}
Please suggest a solution
Disclaimer: I'm the author of following library.
I think lift-combobox could achieve what you want, since it has a feature that let user created the value on-the fly. It use select2 jQuery plugin, so you will have a nice look and feel for the drop-down menu.
For example if you need to get the user-created value, it will simply as the following, note that we usually using Option[T] to denote that the value may not be presented, for example, the user may not selected any item in drop-menu at all:
var friend_name: Option[String] = None
val friendsMenu = new ComboBox(
default = None,
allowCreate = true
) {
// This is where you build your combox suggestion
override def onSearching(term: String): List[ComboItem] = {
val names = List(
ComboItem("f1", "Brian"), ComboItem("f2", "Alice"),
ComboItem("f3", "Luke"), ComboItem("f4", "Smith"),
ComboItem("f5", "Brandon")
)
names.filter(_.text.contains(term))
}
override def onItemSelected(selected: Option[ComboItem]): JsCmd = {
friend_name = selected
// The returned JsCmd will be executed on client side.
Alert("You selected:" + selected)
}
// What you want to do if user added an item that
// does not exist when allowCreate = true.
override def onItemAdded(text: String): JsCmd = {
friend_name = Some(text)
}
}
"#bdayReminder" #> friendsMenu.combobox

Lift Framework - problems with passing url param to Snippet class

I am trying to do a simple case of /author/ and get the Lift to build a Person object based on the id passed in.
Currently i have an Author snippet
class Author(item: Person) {
def render = {
val s = item match { case Full(item) => "Name"; case _ => "not found" }
" *" #> s;
}
}
object Author{
val menu = Menu.param[Person]("Author", "Author", authorId => findPersonById(authorId), person => getIdForPerson(person)) / "author"
def findPersonById(id:String) : Box[Person] = {
//if(id == "bob"){
val p = new Person()
p.name="Bobby"
p.age = 32
println("findPersonById() id = " +id)
Full(p)
//}else{
//return Empty
//}
}
def getIdForPerson(person:Person) : String = {
return "1234"
}
}
What i am attempting to do is get the code to build a boxed person object and pass it in to the Author class's constructor. In the render method i want determine if the box is full or not and proceed as appropriate.
If i change
class Author(item: Person) {
to
class Author(item: Box[Person]) {
It no longer works but if i leave it as is it is no longer valid as Full(item) is incorrect. If i remove the val s line it works (and replace the s with item.name). So how do i do this. Thanks
The Box returned from findPersonById(id:String) : Box[Person] is evaluated and if the Box is Full, the unboxed value is passed into your function. If the Box is Empty or Failure the application will present a 404 or appropriate error page instead.
You can try double boxing your return if you want to handle this error checking yourself (so that the result of this method is always a Full Box).
def findPersonById(id:String) : Box[Box[Person]] = {
if(id == "bob"){
val p = new Person()
p.name="Bobby"
p.age = 32
println("findPersonById() id = " +id)
Full(Full(p))
}else{
return Full(Empty)
}
}
and then this should work:
class Author(item: Box[Person])