Easy way to access POJO properties in groovy? - reflection

I'm new to groovy and still learning my way around. Is there an easy way to get POJO property values in groovy using dot notation? For example, I have the following POJO:
public class MyPOJO {
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
In groovy, I would like to get the value of the name field as follows:
def doSomething (MyPOJO mpj) {
def name = mpj.name
// do something
}
The above does not work. I know that i could still use java getters and setters, but I would like to be able to get to a point where I can dynamically pull pojo values like so:
def doSomething (MyPOJO mpj, String propertyName) {
def propertyValue = mpj.'${propertyName}'
// do something
}
I'm trying to avoid using java reflection. Thanks for the help!

Michal - apologies... the first code snippet was working, the second wasn't.
stempler - that worked! this was gnawing on me. corrected snippet:
def doSomething (MyPOJO mpj, String propertyName) {
def propertyValue = mpj."${propertyName}"
// do something
}

Related

spring mvc rest validation on all method parameters

I would like to find a a way to validate a rest method based on all parameters outside the Controller.
First Question: Is there already a way to do it?
Second Question: If not - how can I hook the validation into spring mvc binding prozess.
A way how it could look like. It would be nice to mark the method with a new #MethodValidation Annotation:
#Validate
#MethodValidation(MyValidator.class)
public Response doSomthing(String param1, Integer param2, Something param3){}
Annotation
#Target({ElementType.METHOD})
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface MethodValidation{
Class<? extends MethodValidator<?, ?>>[] value();
}
Implement a Validator
public class MyValidator implements MethodValidator{
public void validate(Object[] params, Errors errors){
String param1 = (String ) params[0];
Integer param2 = (Integer) params[1];
Something param3 = (Something)params[3];
// .... do some validations
if(error)
errors.reject("Some.error.done");
}
}
what kind of parameters exactly? a lot of spring stuff is actually available in ThreadLocals, if you dare to dig into it.
you CAN inject stuff into the binding process:
#ControllerAdvice
public class FooControllerAdvice {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(
Date.class,
new CustomFooEditor()
);
}
}
and the actual editor:
public class CustomFooEditor extends PropertyEditorSupport {
}
but this doesn't give you that much of an edge over regular validation.
or you can use spring aop triggered by an annotation, then annotate your methods, with the config:
#EnableAspectJAutoProxy(proxyTargetClass=true)
an aspect:
#Aspect
#Component
public class ValidationAspect {
#Pointcut("execution(public * * (..))")
private void anyPublicMethod() {}
#Around("anyPublicMethod() && #annotation(foo)")
public Object all(
ProceedingJoinPoint proceedingJoinPoint,
Foo ann) throws Throwable {
}
[...]
}
an annotation:
#Inherited
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Foo {
}
public String value();
and then annotating your method:
#RequestMapping...
#Foo(value="foo.bar.ValidatorClassname")
public Response x() {
}
... so you see, there's a lot of ways you can go. i'd really like to know what keeps you from using standard validation?
.rm
thanx for the answer.
I hope I am right: The standard validation outside the controller just allows me to to validate each method parameter separately.
I actually get into problems when the validation depends on 2 or more method parameter. This could be in following situation: Some thing is a part of an Object hierarchy:
public class Parent{
private Integer id;
private List<Something> childs;
...
}
public class Something{
private Integer id;
private String name;
...
}
The Constrain: it is not allowed that a Parent has 2 somethings in the list with the same name. For saving a new some thing I am calling the method.
#RequestMapping(
value = "/chargingstation/{parentId}",
method = RequestMethod.Post)
public Response doSomthing(
#PathVariable("parentId") Integer parentId,
Something param3)
Add the parentId to the Something-ModelOject was not an option.
So is there a way to handle this situation with the standard validation?

Change default session provider in ASP.NET

I want to change my session proviced to statically typed - I just hate typing strings because of many many errors I do.
What technology am I using? ASP.NET MVC via EXT.NET MVC
I was trying to do that using web.config but the problem is that after add session state to it visual is not going to compile my code because of that session should be using strings as keys.
I want to use session by enums such as :
public enum SessionEnum{Model}
public class Bar{
void foo(){
Session[SessionEnum.Model] = "blah";
}
}
I am aware that I can create wrapper converting enums to strings but it's not very satisfying solution for me.
public class StorageWrapper{
public object this[SessionEnum enum]{ get{return Session[enum.toString()]}; //+set
}
What I did was create static object for base class for all of my controllers and then I was able to use it across them but after closing and opening the page again I wasn't able to get values from it. I guess I should serialize them somehow but I have no idea how.
Is there any way to do that?
EDIT
My session now looks like this :
[Serializable]
public abstract class DataWrapper<T> : HttpSessionStateBase
{
Dictionary<T, object> Dictionary { get; set; } = new Dictionary<T, object>();
public object this[T a]
{
get
{
try
{
return Dictionary[a];
}
catch
{
return null;
}
}
set { Dictionary[a] = value; }
}
}
[Serializable]
public class SessionWrapper : DataWrapper<SessionNames>
{}
public enum SessionNames { Model, Login, LastOpenedFile }
It's very simple.
Create a UserSession object which does everything you want (holds your values as enum etc), instantiate it, then put it in the session.
var US = new UserSession();
US.stuff = somestuff;
Session["UserSess"] = US
Then you can just always use Session["UserSess"].stuff;
Mmmm, wouldn't you use static const string instead of an enum?
using System.Web;
public static class SessionEnum
{
public static const string Model = "_Session_Model";
public static const string Login = "_Session_Login";
public static const string LastOpenedFile = "_Session_LastOpenedFile ";
}
class test
{
void test()
{
Session[SessionEnum.Model] = "blah";
}
}

WebApi: mapping parameter to header value

I've done a few searches but haven't seem to find anything...
Using WebApi, I would like to map an input parameter to a header value: e.g.
E.g. in controller:
public User GetUser(int id){
...
return user;
}
I want WebApi to map the id parameter to a header value (e.g. X-Auth: 1234)... rather than an URL parameter.
Is this supported?
I don't think this is supported out of the box, like for example with the [FromBody] attribute.
It seems you should be able to achieve this functionality by using Model Binders, as described here. In the model binder you have access to the request and its headers, so you should be able to read the header and set its value to the bindingContext.Model property.
Edit: Reading the article further, it seems a custom HttpParameterBinding and a ParameterBindingAttribute is a more appropriate solution, or at least I would go this way. You could implement a generic [FromHeader] attribute, which does the job. I am also fighting the same problem, so I will post my solution once I have it in place.
Edit 2: Here is my implementation:
public class FromHeaderBinding : HttpParameterBinding
{
private string name;
public FromHeaderBinding(HttpParameterDescriptor parameter, string headerName)
: base(parameter)
{
if (string.IsNullOrEmpty(headerName))
{
throw new ArgumentNullException("headerName");
}
this.name = headerName;
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
IEnumerable<string> values;
if (actionContext.Request.Headers.TryGetValues(this.name, out values))
{
actionContext.ActionArguments[this.Descriptor.ParameterName] = values.FirstOrDefault();
}
var taskSource = new TaskCompletionSource<object>();
taskSource.SetResult(null);
return taskSource.Task;
}
}
public abstract class FromHeaderAttribute : ParameterBindingAttribute
{
private string name;
public FromHeaderAttribute(string headerName)
{
this.name = headerName;
}
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
return new FromHeaderBinding(parameter, this.name);
}
}
public class MyHeaderAttribute : FromHeaderAttribute
{
public MyHeaderAttribute()
: base("MyHeaderName")
{
}
}
Then you can use it like this:
[HttpGet]
public IHttpActionResult GetItem([MyHeader] string headerValue)
{
...
}
Hope that helps.
WebApi on DotNet Core has a has some additional attributes for extracting data from the request. Microsoft.AspNetCore.Mvc.FromHeaderAttribute will read from the request head.
public ActionResult ReadFromHeader([FromHeader(Name = "your-header-property-name")] string data){
//Do something
}
Thank you filipov for the answer.. I took your code and modified it a bit to suit my needs. I am posting my changes here in case anyone can make use of this.
I made 2 changes.
I liked the idea of the FromHeaderAttribute, but without subclassing. I made this class public, and require the user to set the param name.
I needed to support other data types besides string. So I attempt to convert the string value to the descriptor's parameterType.
Use it like this:
[HttpGet]
public void DeleteWidget(long widgetId, [FromHeader("widgetVersion")] int version)
{
...
}
And this is my FromHeaderBinding
public class FromHeaderBinding : HttpParameterBinding
{
private readonly string _name;
public FromHeaderBinding(HttpParameterDescriptor parameter, string headerName)
: base(parameter)
{
if (string.IsNullOrEmpty(headerName)) throw new ArgumentNullException("headerName");
_name = headerName;
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
{
IEnumerable<string> values;
if (actionContext.Request.Headers.TryGetValues(_name, out values))
{
var tempVal = values.FirstOrDefault();
if (tempVal != null)
{
var actionValue = Convert.ChangeType(tempVal, Descriptor.ParameterType);
actionContext.ActionArguments[Descriptor.ParameterName] = actionValue;
}
}
var taskSource = new TaskCompletionSource<object>();
taskSource.SetResult(null);
return taskSource.Task;
}
}

Removing the class name before calling a custom function?

I have a function for getting a string to have only the first letter to be uppercase.
public class Class1
{
public static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1).ToLower();
}
}
Example:
string MyName = "john";
string result = Class1.UppercaseFirst(MyName)
Result: "John"
Is it possible to remove the "Class1." before the call to the function?
Make it an extension method then you can call it like "john".UppercaseFirst();
You just need to declare your class as static and change the signature to the following
public static string UppercaseFirst(this string s)
{...
You could write an extension method:
public static class StringExtension
{
public static string UppercaseFirst(this string text)
{
// ..
}
}
Then you can use it like this:
string uppercase = "myText".UppercaseFirst();
Only if you call the static method from inside the same Class1. If you call it from outside the class you'll need the Class1 specifier.
However, if you make it an extension method in a static class, you can call it directly on all strings.

Verifying a method called with certain derived parameter

Consider the following snippet;
public enum ReportType {Monthly,Quarterly}
public class BaseReport
{
public ReportType ReportType {get;set;}
}
public class MonthlyReport : BaseReport
{
public String month = "January"
public MonthlyReport() { ReportType = Monthly;}
}
public class Foo
{
public virtual void AddReport(BaseReport report);
}
[Test]
public void Test1()
{
var mock = new Mock<Foo>(){CallBase =true};
var report = new MonthlyReport();
mock.Object.AddReport(report);
}
Well I am trying to verify if the AddReport() is called with certain parameter here;
mock.Verify(x => x.AddReport(It.Is<MonthlyReport>(p => p.month == "January" &&
p.ReportType == ReportType.Monthly)));
As I feared, it doesn't work with a MonthlyReport parameter for Is<> even though it is derived from BaseReport. If I use Is,then I can't use p.month in the expression, and I am not that proficient with c# to know whether I can use if(p is MonthlyReport) in a lambda expression or more importantly, it would work as intended.
How can I approach this problem? Please note that the mock is partial, Although I can live with
Setup approach with callbacks if it is neatly solves my problem.
Any pointers would be greatly appreciated...

Resources