I have a restservice running by exposing a simple domain class. I can acces by
http://localhost:8080/Bic/bic/17.json
and I get:
{"class":"org.strotmann.bic.BankIdentCode","id":17,"bankname":"ABK-Kreditbank","bic":"ABKBDEB1XXX","blz":10030400,"ort":"Berlin","plz":10115}
I want to acces by something like blz=10030400 or any other item of the domain class except the id.
How to ?
peter
Dortmund, Germany
the controller action code (you should have posted here!) can look like:
def bic(){
def entry = params.find{ k, v -> Bic.metaClass.hasMetaProperty k }
if( entry )
render( Bic.withCriteria( uniqueResult:true ){ eq entry.key, entry.value } as JSON )
else
render text:'not found!`
}
Related
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!
I have 3 modules, Let say module A, B are two Parent modules, C is child module(junction) in A and B.
When Quick Create of C from Deatil view of A, on select of the relate module B, need to populate B module data to some other field of C. and need to pass some data of A to some field of C
(In Detail view of A, C is subpanel and in C a relate field to B). hope I am clear
Im using suagrcrm 6.5.x
can any one help me on this..
If I get you right maybe this helps:
write a view in "modules/YOURMODULE/views.view.subpanelquickcreate.php" and do something like this:
require_once('include/EditView/SubpanelQuickCreate.php');
class YOURMODULESubpanelQuickCreate extends SubpanelQuickCreate
{
function process($module)
{
if ($_REQUEST['target_action'] == 'QuickCreate') {
$this->ev->view = 'QuickCreate';
}
$form_name = 'form_Subpanel' . $this->ev->view . '_' . $module;
$this->ev->formName = $form_name;
if ($_REQUEST['return_module'] === 'MODULE_A' && isset($_REQUEST['MODULE_A_id'])) {
$this->prefill($_REQUEST['MODULE_A_id']);
}
$this->ev->process(true, $form_name);
echo $this->ev->display(false, true);
}
function prefill($id)
{
$modA = new ModA();
$modA->retrieve($id);
$this->ev->focus->modA_id = $modA->id;
$this->ev->focus->modA_name = $modA->name;
$this->ev->focus->company_name = ...
}
}
Like that when you click on create inside of the subpanel you prefill YOURMODULE with values from the current modules detailview.
I've created a groovy script for the new Jenkins Workflow Plugin, https://github.com/jenkinsci/workflow-plugin. I want it to send a mail to the user who started the job when it needs input for the next step. I've tried to search the API but I can't find anything about getting the users email address.
I would think of something like this.
import hudson.model.User
def user = User.current()
def mailAddress = user.getMailAddress()
Is there a way to get the current Jenkins user' address in groovy?
I found a way:
import hudson.model.AbstractProject
import hudson.tasks.Mailer
import hudson.model.User
def item = hudson.model.Hudson.instance.getItem(env.JOB_NAME)
def build = item.getLastBuild()
def cause = build.getCause(hudson.model.Cause.UserIdCause.class)
def id = cause.getUserId()
User u = User.get(id)
def umail = u.getProperty(Mailer.UserProperty.class)
print umail.getAddress()
You can access the object of the current user with the method current()
def user = hudson.model.User.current();
The email address can be retrieved in the same way as to what you have done in your answer.
print user.getProperty(hudson.tasks.Mailer.UserProperty.class).getAddress();
import hudson.tasks.Mailer;
import hudson.model.User;
import hudson.model.Cause;
import hudson.model.Cause.UserIdCause;
def cause = build.getCause(hudson.model.Cause$UserIdCause)
def id = cause.getUserId()
User u = User.get(id)
def umail = u.getProperty(Mailer.UserProperty.class)
print umail.getAddress()
If you have access to the build variable in the Java code of your plugin (for instance in the setUp() method of the class that extends BuildWrapper), you can get the currently logged user this way :
#Override
public MyJenkinsPlugin setUp(AbstractBuild build, Launcher launcher, BuildListener listener)
String connectedUser = build.getCause(Cause.UserIdCause.class).getUserId();
String mail = User.get(connectedUser.getProperty(hudson.tasks.Mailer.UserProperty.class).getEmailAddress()
...
}
I have not been able to get the logged user using User.current().getId(), it always returned me 'SYSTEM'.
Hope it helps!
You can get the author name and then use it for an example on a mailing registry or something like that:
def author = ""
def changeSet = currentBuild.rawBuild.changeSets
for (int i = 0; i < changeSet.size(); i++)
{
def entries = changeSet[i].items;
for (int i = 0; i < changeSet.size(); i++)
{
def entries = changeSet[i].items;
def entry = entries[0]
author += "${entry.author}"
}
}
print author;
You can use the following routine:
import hudson.tasks.Mailer;
import hudson.model.User;
/**#
* Get user's email
*
* #param id null for a user who triggered the current build or name otherwise
* #return user's email
*/
def getUserEmail(String id=null) {
User user = User.getById(id ?: currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(), false)
user?.getProperty(Mailer.UserProperty.class).getAddress()
}
My input.xml
<z1:BookNames name="Groovy" dataType="INTEGER" xmlns:z0="messages" xmlns:z2="base" xmlns:z3="number" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:z1="bookcat">
<z3:BookCost>
<z3:IntegerValue>1106</z3:IntegerValue>
</z3:BookCost>
</z1:BookNames>
My Code-
document = parse(new FileReader('input.xml'))
rootElement = document.documentElement
println rootElement
use(groovy.xml.dom.DOMCategory)
{
println rootElement.'#dataType'
cf = rootElement.'z3:BookCost'
}
I'm trying to fetch book cost but unsuccessful so far. Can you throw ideas here. I can't declare prefix z3 as 'z3:BookCost' z3 can be anything in input xml. But namespace value can be hard-coded in code.
Here's a way using XmlSlurper:
new File( 'input.xml' ).withReader { x ->
new XmlSlurper().parse( x ).with { root ->
println root.#dataType
println root.BookCost.IntegerValue
}
}
DOMCategory isn't namespace aware (afaik)
I want to copy object properties to another object in a generic way (if a property exists on target object, I copy it from the source object).
My code works fine using ExpandoMetaClass, but I don't like the solution. Are there any other ways to do this?
class User {
String name = 'Arturo'
String city = 'Madrid'
Integer age = 27
}
class AdminUser {
String name
String city
Integer age
}
def copyProperties(source, target) {
target.properties.each { key, value ->
if (source.metaClass.hasProperty(source, key) && key != 'class' && key != 'metaClass') {
target.setProperty(key, source.metaClass.getProperty(source, key))
}
}
}
def (user, adminUser) = [new User(), new AdminUser()]
assert adminUser.name == null
assert adminUser.city == null
assert adminUser.age == null
copyProperties(user, adminUser)
assert adminUser.name == 'Arturo'
assert adminUser.city == 'Madrid'
assert adminUser.age == 27
I think the best and clear way is to use InvokerHelper.setProperties method
Example:
import groovy.transform.ToString
import org.codehaus.groovy.runtime.InvokerHelper
#ToString
class User {
String name = 'Arturo'
String city = 'Madrid'
Integer age = 27
}
#ToString
class AdminUser {
String name
String city
Integer age
}
def user = new User()
def adminUser = new AdminUser()
println "before: $user $adminUser"
InvokerHelper.setProperties(adminUser, user.properties)
println "after : $user $adminUser"
Output:
before: User(Arturo, Madrid, 27) AdminUser(null, null, null)
after : User(Arturo, Madrid, 27) AdminUser(Arturo, Madrid, 27)
Note: If you want more readability you can use category
use(InvokerHelper) {
adminUser.setProperties(user.properties)
}
I think your solution is quite good and is in the right track. At least I find it quite understandable.
A more succint version of that solution could be...
def copyProperties(source, target) {
source.properties.each { key, value ->
if (target.hasProperty(key) && !(key in ['class', 'metaClass']))
target[key] = value
}
}
... but it's not fundamentally different. I'm iterating over the source properties so I can then use the values to assign to the target :). It may be less robust than your original solution though, as I think it would break if the target object defines a getAt(String) method.
If you want to get fancy, you might do something like this:
def copyProperties(source, target) {
def (sProps, tProps) = [source, target]*.properties*.keySet()
def commonProps = sProps.intersect(tProps) - ['class', 'metaClass']
commonProps.each { target[it] = source[it] }
}
Basically, it first computes the common properties between the two objects and then copies them. It also works, but I think the first one is more straightforward and easier to understand :)
Sometimes less is more.
Another way is to do:
def copyProperties( source, target ) {
[source,target]*.getClass().declaredFields*.grep { !it.synthetic }.name.with { a, b ->
a.intersect( b ).each {
target."$it" = source."$it"
}
}
}
Which gets the common properties (that are not synthetic fields), and then assigns them to the target
You could also (using this method) do something like:
def user = new User()
def propCopy( src, clazz ) {
[src.getClass(), clazz].declaredFields*.grep { !it.synthetic }.name.with { a, b ->
clazz.newInstance().with { tgt ->
a.intersect( b ).each {
tgt[ it ] = src[ it ]
}
tgt
}
}
}
def admin = propCopy( user, AdminUser )
assert admin.name == 'Arturo'
assert admin.city == 'Madrid'
assert admin.age == 27
So you pass the method an object to copy the properties from, and the class of the returned object. The method then creates a new instance of this class (assuming a no-args constructor), sets the properties and returns it.
Edit 2
Assuming these are Groovy classes, you can invoke the Map constructor and set all the common properties like so:
def propCopy( src, clazz ) {
[src.getClass(), clazz].declaredFields*.grep { !it.synthetic }.name.with { a, b ->
clazz.metaClass.invokeConstructor( a.intersect( b ).collectEntries { [ (it):src[ it ] ] } )
}
}
Spring BeanUtils.copyProperties will work even if source/target classes are different types. http://docs.spring.io/autorepo/docs/spring/3.2.3.RELEASE/javadoc-api/org/springframework/beans/BeanUtils.html