struts2: select tag doesn't like beans with "parameters" property? - properties

I have a base class ReportElement which has type property:
public abstract class ReportElement {
private ReportElementType type;
public ReportElementType getType() {
return type;
}
public void setType(ReportElementType type) {
this.type = type;
}
}
ReportElementType is just an enum with specified code and i18nKey properties for each element. I have a couple of subclasses of ReportElement, each of them introducing their own properties. One of them is Plot:
public class Plot extends ReportElement {
public Plot() {
setType(ReportElementType.PLOT);
}
private Collection<Parameter> parameters = new ArrayList<Parameter>();
public Collection<Parameter> getParameters() {
return parameters;
}
}
On some page I needed to display a collection of different ReportElement instances, so I just used struts2 select tag:
<s:select list="myElements" listKey="type.code" listValue="type.i18nKey" size="20"/>
This worked like a charm for every element except for Plot instaces. Instead of invoking getType().getCode() or getType().getI18nKey() plain toString() was invoked on every instance of Plot! After several hours of fun debugging I noticed that during tag evaluation Plot's getParameters() method is called! So it seems struts was trying to evaluate type.code and type.i18nKey using getParameters() method! Failing to do that it ignored the existence of the properties, that I have clearly specified for usage!
After renaming getParameters to a kind of odd name like getParamms the problem gone. Also the problem hasn't occured when using iterator tag together with property tag instead of select tag.
Does anyone have an idea WHY struts select tag uses parameters property of my bean, when I have clearly specified what property should be used? Is it some "cool" feature or a bug?
P.S. I use struts 2.2.3.1

The argument used in all the FreeMarker templates representing a tag's parameters is called parameters. By providing a parameters property that takes precedence, S2 was unable to get to the object on the stack containing the tag's parameters.
It's neither a cool feature nor a bug, it's just how the templates are implemented. Checking the template source may have saved the few hours of debugging.

Found corresponding issue in struts JIRA: https://issues.apache.org/jira/browse/WW-3268
2.3 is specified as fix version.

Related

How to iterate Apache velocity template variable attributes

As title, is there any way to iterate or display Apache velocity template attributes?
for example, I have following code :
<code>
${ctx.messages.headerMessage}
</code>
And I want to know how many other attributes the variable ${ctx} has
It's only possible to discover and to loop on an object properties (that is, the ones with getters and/or setters) if you can add a new tool to your Velocity context. If you can't, you're rather stuck.
There are several ways to do this, I illustrate below how to do this with commons-beanutils.
First, add Apache commons-beanutils in your class path, and add it to your Velocity context from Java:
import org.apache.commons.beanutils.PropertyUtils;
...
context.put("beans", new PropertyUtils());
...
One remark: if you do not have access to the Java part, but if by chance commons-beanutils is already in the classpath, there is one hakish way of having access to it: #set($beans = $foo.class.forName('org.apache.commons.beanutils.PropertyUtils').newInstance()).
Then, let's say that I have the following object:
class Foo
{
public boolean isSomething() { return true; }
public String getName() { return "Nestor"; }
}
which is present in my context under $foo. Using your newly $beans properties introspector, you can do:
#set ($properties = $beans.getPropertyDescriptors($foo.class))
#foreach ($property in $properties)
$property.name ($property.propertyType) = $property.readMethod.invoke($foo)
#end
This will produce:
bar (boolean) = true
class (class java.lang.Class) = class Foo
name (class java.lang.String) = Robert
(you'll need to filter out the class property, of course)
One last remark, though. Templates are for coding the View layer of an MVC application, and doing such a generic introspection of objects in them is rather inadequate in the view layer. You're far better of moving all this introspection code on the Java side.

Jackson Mixin's Ignoring a property when using #JsonUnwrapped but only some cases

With Jackson i'm using Mixin interfaces to Serialize.
Suppose i have a common class used by multiple classes, here the Mixin of that class:
#JsonPropertyOrder({"id", "name"})
interface SharedMixin {
String getId();
String getName();
}
That Mixin is used by multiple Mixin's using #JsonUnwrapped annotation, like the following:
#JsonPropertyOrder({"code", "sharedMixin"})
public interface AnotherMixin {
String getCode();
#JsonUnwrapped
SharedMixin getSharedMixin();
}
That works fine, it unwraps all the properties from the SharedMixin Interface. But there's a specific case where i want to ignore one property of the SharedMixin when Unwrapping in the parent Mixin, suppose i want to ignore the name field.
I tried the following but without success.
#JsonPropertyOrder({"otherField", "sharedMixin"})
public interface AnotherMixin2 {
String otherField();
#JsonUnwrapped
SharedMixin getSharedMixin();
#JsonIgnore()
String getName();
}
I also tried using "#JsonIgnoreProperties({"name"})" but neither it worked, looks like the property still there when serializing but with an empty value.
Please notice that i can not use #JsonIgnore() inside the SharedMixin because it will ignore the field in all the classes that use it and they are multiple.
Looks like this is a Bug in Jackson's library, #JsonUnwrapped and #JsonIgnoreProperties does not work very well together.
https://github.com/FasterXML/jackson-dataformats-text/issues/77
True, #JsonIgnore and #JsonIgnoreProperties do not work with #JsonUnwrapped properly, but placing #JsonIgnoreProperties on the field itself helped at least with regular serializing, without mixins:
How to ignore specific sub-field of an unwrapped field (CSV)

jdto superclass boolean field binding incorrect value

public class Model {
}
public class SuperclassDTO {
private boolean funny = true;
public boolean isFunny() {
return funny;
}
public boolean setFunny(boolean f) {
this.funny = f;
}
}
public class SubclassDTO extends SuperclassDTO {
}
new SubclassDTO().isFunny() //returns true
SubclassDTO dto = binder.bindFromBusinessObject(SubclassDTO.class, new Model());
dto.isFunny(); //returns false!!!!
Isn't this weird? Model class does not have a "funny" field but somehow dto is bind with a wrong value. First I thought jDTO required "getFunny" convention, so it couldn't read the value and just set it "false" but changing the getter name to "getFunny" does not resolve the issue, plus I'm not allowed to modify SuperclassDTO. How can I bind the correct value?
Jdto version 1.4 by the way...
The behavior you're experiencing is a "side effect" of the convention over configuration approach. All the fields on the DTO are configured unless you mark them as transient, either by using the #DTOTransient annotation or the transient configuration on the XML file. If a configured field does not have a corresponding field on the source bean, it will be set with default values and that is the reason why you're experiencing this behavior.
You have some options to overcome this issue:
Add the #DTOTransient annotation to the DTO.
Since you're not able to modify the DTO, you could configure it through XML.
Use Binding lifecycle to Restore the value. By adding code on the subclass.
You might as well submit a bug report on the jDTO issue tracker on github.

AOP - Injecting a property with a dynamically computed value

(or "Using LocationInterceptionAspect and IInstanceScopedAspect together")
Using Postsharp I'm trying to inject a property into a target class using 'IntroduceMember' and then using the 'OnGetValue' functionality of LocationInterceptionAspect dynamically give it a value on inspection.
Originally I thought that I'd need two separate aspects, one for the field injection and one for the location interception but managed to combine the two by implementing the IInstanceScopedAspect interface and inheriting from LocationInterceptionAspect.
The problem is that if I set a breakpoint I will see the property that's been injected, but if I set another breakpoint in the OnGetValue method (that gets fired for each property on the class) I can't see it...
Here's some sample code:
[Serializable]
class DALDecoratorWrapper : LocationInterceptionAspect, IInstanceScopedAspect
{
public override void OnGetValue(LocationInterceptionArgs args)
{
if (args.LocationName == "Type")
{
args.Value = "computed value here";
}
args.ProceedGetValue();
}
[IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
public String Type { get; set; }
I was also hoping there was a better way of doing this than overriding OnGetValue as that's called for each getter where really I want to only target the getter of the property that's been injected
Cheers

fluent nhibernate polymorphism. how to check for type of class

I have an Icon which has a Content (one to one) relationship.
public class Icon
{
public virtual Content Content {get; set;}
}
By default, it is lazy loaded which is what I want.
However, at some point in the code, I need to check what kind of Content is, Content being polymorphic, something like
if(icon.Content is TextContent)
{
...
}
Icon is part of another association and it is automatically obtained by the NHibernate, I do not get it manually.
What is the recommended way of checking for the actual type in this situation?
I can have a specific property like ContentType which will be an enum in order to identify the actual content type, but I am looking to know if there's a different way.
If you want to do that kind of check, you have to remove the proxy from the property.
There is a few ways to do it:
If you have access to the session call:
session.PersistenceContext.Unproxy(icon.Content);
Implement a virtual method (in a base class if possible) that forces the removal of the proxy by returning the instance with the proper type.
public virtual U As<U>() where U : YourType {
return this as U;
}
Disable the lazy initialization of the property.
This is very similar to another recent question.
To add to csanchez's list, a fourth method is to add a Self property to the Content base class that returns the un-proxied type:
public virtual void Self
{
get { return this; }
}
And a fifth method is to use 'lazy="no-proxy"` in the mapping as described on Ayende's blog.
Thanks for the suggestions but meanwhile I found an interesting solution, better I think.
Using the Visitor pattern, I can define an IconContent visitor and pass an Action to be executed to it.
For example, suppose there is a TextContent and an ImageContent, it will be something like this:
IconContentVisitor.Func(()=> { Console.WriteLine("this is TextContent"; }, ()=> { Console.WriteLine("this is ImageContent"));
Idea came from here: http://mookid.dk/oncode/archives/991