How to create properties class handler with using default properties - java

phew there are lots of questions from my side these days, but:
I'm looking for the best solution of how to handle properties file when one of them are missing, than use default values. I'm using:
serenity-bdd, selenium, java, maven.
My solution is:
Create Interface with constants
Create handler which is going to have at least 3 methods like,
getDefaultProperties,
getCustomProperties
and last is method which should return list of properties, but if defaultValue != customValue than override and put to array and return, then I'm going to handle each parameter where I need.
Appreciate for advice,
Thank you.

Related

Is there a pattern to force the setting of a property in an injected component?

I am wondering if there is a pattern that forces the user of my component to set a property after it is autowired. For example i have this:
#SpringComponent
#PrototypeScope
public class MyAutowiredClass {
private String myVariabeThatTheUserShouldSet;
public MyAutowiredClass(someOtherStuff ...(not my StringVariable)){
}
}
In this example how to i force myVariabeThatTheUserShouldSet to be set from the user of this component?
Well it's a bit complicated. If it wasn't in spring context you could just add that variable to the constructor and make it "required" like that. So to achieve that in a Spring context I would advise the following:
If possible pass that value as part of the dependency injection instead of trying to work around it. I understand it is something dynamic but still usually it would have business meaning and there is a way to do it. For example if you want the current user email you can add some Service that retrieves that value and pass that service to your component and extract that value from there. Or if you want some company configuration you can add a Service that gives you that value etc. It is the "Spring" way and I would lean towards that.
A simpler solution would be to add that required field to the methods signature of the methods that actually need it. It will overload the signatures by one field but it would force the users to pass a value. If you need that field for a couple of methods and not for the correct work of the component then it would be the easiest to implement/understand solution.
Add a setter for that value and throw exception if it is not set. That would be the worse though because will require try/catches if the exception is checked and if it is not people will forget to set the field so I would avoid that solution.

GWT interface like Constants

In my application I need to use dynamic localization, so I cannot use Constants interface. I did use Constants for a while, but now I need texts to be changed without compiling so I had to find some other way.
So I am using Dictionary now. The thing is, when I now want to use text in UiBinder, I can only use methods without arguments. So I created class "StringIdentifiers" where I have the same methods I previously had in MyConstants, but I have to specify a body here for every method to return the specified String.
So for example I have:
Dictionary locale = Dictionary.getDictionary("myJsObjectWithStrings");
//and then the methods for returning the actual strings from the JS object
String loading(){
return locale.get("loading");
}
I would like the method to only be
String loading();
since the rest is always the same with the name of the method appearing as String parameter in the get() method. Possibly even returning some default value when the String is missing in the JS object. But I do not know how to do that. I checked the Constants interface, but I do not really understand the code there. Can someone please give me an example how to implement such a thing?
There is no standard feature in GWT to do this, but you could create one yourself. It's a bit of a stretch, but it should work by using the GWT generator mechanisch. In global terms it should work as follows:
Create an interface (say MyMessages) with a the method names.
To use it use MyMessages message = GWT.create(MyMessages.class). Where you need the text message.loading().
Create a generator that generates an class implementing the interface. This class will created at compile time and should contain the implementation of the interface methods, like in your example.
Add a generate-with tag in your gwt.xml file to make it work.
This is a bit of a brief explanation, but I hope it helps. For more background information about generators see: What is the use GWT generator? or http://blog.arcbees.com/2015/05/26/how-to-write-gwt-generators-efficiently/
You could even reuse some of GWT's annotation's of the i18n to add for example default texts. Add the annotation to your interface and in the generator scan the annotation and use it in the code generation part.

Dynamically setting and getting bean properties in XPages

Just another Java problem (I'm a noob, I know): is it possible to use dynamic property binding in a Custom Control with a dynamic property getter in a Java bean?
I'll explain. I use this feature extensively in my Custom Controls:
<xp:inputTextarea id="DF_TiersM">
<xp:this.value><![CDATA[#{compositeData.dataSource[compositeData.fieldName]}]]></xp:this.value>
This is used in a control where both datasource and the name of the field are passed as parameters. This works, so far so good.
Now, in some cases, the datasource is a managed bean. When the above lines are interpreted, apparently code is generated to get or set the value of ... something. But what exactly?
I get this error: Error getting property 'SomeField' from bean of type com.sjef.AnyRecord which I guess is correct for there is no public getSomeField() in my bean. All properties are defined dynamically in the bean.
So how can I make XPages read the properties? Is there a universal getter (and setter) that allows me to use the name of a property as a parameter instead of the inclusion in a fixed method name? If XPages doesn't find getSomeField(), will it try something else instead, e.g. just get(String name) or so?
As always: I really appreciate your help and answers!
The way the binding works depends on whether or not your Java object implements a supported interface. If it doesn't (if it's just some random Java object), then any properties are treated as "bean-style" names, so that, if you want to call ".getSomeField()", then the binding would be like "#{obj.someField}" (or "#{obj['someField']}", or so forth).
If you want it to fall back to a common method, that's a job for either the DataObject or Map interfaces - Map is larger to implement, but is more standard (and you could inherit from AbstractMap if applicable), while DataObject is basically an XPages-ism but one I'm a big fan of (for reference, document data sources are DataObjects). Be warned, though: if you implement one of those, EL will only bind to the get or getValue method and will ignore normal setters and getters. If you want to use those when present, you'll have to write reflection code to do that (I recommend using Apache BeanUtils).
I have a post describing this in more detail on my blog: https://frostillic.us/f.nsf/posts/expanding-your-use-of-el-%28part-1%29

Jackson JSON Prefixing

I'm currently using RestEasy(2.3.6) with Jackson(1.9.9) and needing to prefix my JSON arrays with '{} &&' in order to prevent JSON hijacking.
I'm new to Jackson and am having a really hard time understanding where to insert anything like this. I'm not even sure where to insert something like this to make it happen all the time, and I would like to take it one step further and be able to specify to only prefix return values that contain JSON arrays and not regular objects.
I imagine there is a class somewhere I need to subclass and override a method, and then register that class somehow. Has anyone ever done anything like this?
Jukka, the question you linked to led me to a solution. I extended JacksonJsonProvider, and overrode the writeTo() method. There are a few conditions in there and I was able to add jg.writeRaw("{}&&"); before each place it writes the value. Also, since I'm using Spring, I had to annotate my class with #Component in order for it to be found.
Also another gotcha with creating your own JsonProvider subclass is your rest methods must have #Produces('application/json') (you should always be explicit with these anyway) or else the default JsonProvider will be used.

Session atrribute is missing a List

I have a very strange situation. I´m working on a pretty big Java application with many bugs, and I found this one today.
I´ll try to explain the situation without posting code because the methods are way too long and I have identified and isolated the specific problem. Here it is:
I have a session attribute set on a Controller class. The attribute has several fields, a couple of Strings, a couple of int and an ArrayList of a certain object type. It is set like this:
request.getSession().setAttribute(Constants.SESSION_LIST_SEARCH, beanList);
Then there is another Controller class where I need to read this attribute, it goes like this:
request.getSession().getAttribute(Constants.SESSION_LIST_SEARCH);
When the controller gets the attribute (with the proper cast) the Strings and the int fields are there, but the ArrayList it´s empty.
I couldn't find an answer so in an act of desperation I tried to "clone" the list to see what happened, so it goes like this:
request.getSession().setAttribute(Constants.SESSION_LIST_SEARCH, beanList);
/* Desperate developer */
ArrayList<ActivityBean> duplicatedList = new ArrayList<ActivityBean>();
for(ActivityBean foo:beanList.getActivityBean()){
duplicatedList.add(foo);
}
request.getSession().setAttribute("duplicatedList",duplicatedList);
This workaround does the trick (now I can read the bean "duplicatedList" from the session correctly) but it just doesn't seem right that the original bean loses the ArrayList on some point and still maintain the other fields.
Thanks in advance
It seems that somewhere else in your application, some code is modifying the List (since you said that it's not null but empty - if it was null I'd expect that it was removed from context at all by some other part of code). Maybe after putting List to the context some code still maintains reference and operates on it?
You can try to do the following:
request.getSession().setAttribute(Constants.SESSION_LIST_SEARCH, Collections.unmodifiableList(beanList));

Categories