java calling the Class Attribute by variable - java

I want to call class Attributes by variable .
fo example
Billing.SKU_NAME_PREMIUM1
I want:
String a = 'SKU_NAME_PREMIUM1';
Billing.a
edit:
I want to use variable for Attribute name in
SharedPreferences.Editor editor = shared.edit();
editor.putBoolean(Billing.KEY_PREMIUM_VERSION, true);
Because the class Billing has more than 30 attributes and select the attribute at runtime Depending on the user's choice

It looks like you are looking for variables. Now assuming that type of KEY_PREMIUM_VERSION is int we can use
SharedPreferences.Editor editor = shared.edit();
int ver = Billing.KEY_PREMIUM_VERSION;//variable `ver` will
//copy value of Billing.KEY_PREMIUM_VERSION
editor.putBoolean(ver, true);

You can use Class.getField(name). Note: Using reflection is not recommended in production / final code
Object o = ...;
Field f = o.getClass().getField("a");

Related

Spring SPEL collection projection

A simple question on SPEL collection selection.
Look at section 10.5.17 Collection Selection on this page
https://docs.spring.io/spring/docs/4.3.10.RELEASE/spring-framework-reference/html/expressions.html
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == 'Serbian']").getValue(societyContext);
What i need is the selection 'Serbian' to come from outside and not be a fixed hard coded String.
Just for arguments sake consider that, we could get it as "selectedNationality" from the same society class from the same page in the link.
Modified class with selectedNationality
public class Society {
private String name;
public static String Advisors = "advisors";
public static String President = "president";
private List<Inventor> members = new ArrayList<Inventor>();
private Map officers = new HashMap();
// new selector field
private String selectedNationality;
......
}
New Selection
The new selection SPEL would look like
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == selectedNationality]").getValue(societyContext);
When we try that the error is that "selectedNationality" is not a part of the Member object.
Does that mean that for collection selection in spring expression language we would need a hard coded String ? If yes does anyone know why ?
Found out how to do it. So the way is to use variables
see 10.5.11 Variables # [https://docs.spring.io/spring/docs/4.3.10.RELEASE/spring-framework-reference/html/expressions.html][1]
Set Variable
So in our case we wold do this set variable :
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
context.setVariable("selectedNationality ", "Serbian");
New Selection
The new selection SPEL would look like this with #selectedNationality
List<Inventor> list = (List<Inventor>) parser.parseExpression(
"Members.?[Nationality == #selectedNationality]").getValue(societyContext);
Works like a charm !

How to get a string from .properties file and use it in the same .properties file

Is there a way to retrieve the value of a var in a .properties file and use is inside the same .properties file?
Insted of this (where I have to write manually the words 'Main Menu' in every line)
mainMenuTitle = Main Menu
NotBlank.menu.title = the field 'Main Menu' can't be null
Size.menu.title = the field 'Main Menu' must contains 10 characters
I want something like this (where I get automatically the value of the var 'mainMenuTitle')
mainMenuTitle = Main Menu
NotBlank.menu.title = the field **mainMenuTitle** can't be null
Size.menu.title = the field **mainMenuTitle** must contains 10 characters
You can get both message separately and then make a replace to inject the title
#Inject
public MessageSource messageSource;
public static String getMessage(String messageKey1, String messageKey12) {
String title = messageSource.getMessage(messageKey1, arguments, locale);
String message = messageSource.getMessage(messageKey2, arguments, locale).replace("**mainMenuTitle**", title);
}
This May be what you want, its a bit old , but may work for your needs.
Enabling constant substitution in Property Values
You can substitute a constant anywhere in the property value, and even have more than one constant within a value, as in the following example:
CONST_1 = shoes and ships
CONST_2 = sealing wax
SomeValue = {CONST_1} and {CONST_2}
In this example, the "SomeValue" property evaluates to "shoes and ships and sealing wax."

By using setters in model class Saved data is saved repeatedly?

By using setters and getters class, I am setting values to MusicDetailsObject(pojo class) when setting first value it is set, then setting second value it is set and also replacing first value and so on...... setting values using loop:
for(int k=0;k<songs.length();k++)
{
JSONObject songObject = songs.getJSONObject(k);
//mName.add(songObject.getString("name"));
mObject.setmName(songObject.getString("name"));
//mURL .add(songObject.getString("url"));
mObject.setmURL(songObject.getString("url"));
//mListId .add(songObject.getString("id"));
mObject.setmID(songObject.getString("id"));
mAlbumList.add(mObject);
}
first time setting values as
array1{id = 101
name = Jigarthanda}
When setting value second time it showing like this:
array1{id = 102
name = Mundasupatti}, array1{id = 102
name = Mundasupatti}
so, please let me know how to set an individual value.
Thanks in advance.
The issue is that, inside the loop, you never create a new instance of mObject, so the only instance you have is getting reused.
for(int k=0;k<songs.length();k++){
JSONObject songObject = songs.getJSONObject(k);
mObject = new MyObject() // -> NOW you are assigning values to a different instance.
//mName.add(songObject.getString("name"));
mObject.setmName(songObject.getString("name"));
//mURL .add(songObject.getString("url"));
mObject.setmURL(songObject.getString("url"));
//mListId .add(songObject.getString("id"));
mObject.setmID(songObject.getString("id"));
mAlbumList.add(mObject);
}

Setting field value to null with reflection

I am setting a variable value to null, but having problem with it:
public class BestObject {
private Timestamp deliveryDate;
public void setDeliveryDate(Timestamp deliveryDate) {
this.deliveryDate = deliveryDate;
}
}
BeanUtils.setProperty(new BestObject(), "deliveryDate", null); // usually the values are not hardcoded, they come from configuration etc
This is the error:
org.apache.commons.beanutils.ConversionException: No value specified
at org.apache.commons.beanutils.converters.SqlTimestampConverter.convert(SqlTimestampConverter.java:148)
at org.apache.commons.beanutils.ConvertUtils.convert(ConvertUtils.java:379)
at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:999)
Basically it is trying to set a java.sql.Timestamp value to null, but it is not working for some reason.
On the other hand, I am using reflection wrapper BeanUtils(http://commons.apache.org/proper/commons-beanutils/), maybe this is possible with plain reflection?
I managed to do it with standard reflection.
java.lang.reflect.Field prop = object.getClass().getDeclaredField("deliveryDate");
prop.setAccessible(true);
prop.set(object, null);
It can be done by simple trick
Method setter;
setter.invoke(obj, (Object)null);
A similar complaint (and workaround) was posted in the bug tracker for BeanUtils. See https://issues.apache.org/jira/browse/BEANUTILS-387
Book book = new Book();
Class<?> c = book.getClass();
Field chap = c.getDeclaredField("chapters");
chap.setLong(book, 12)
System.out.println(chap.getLong(book));
[Oracle Offical Source] https://docs.oracle.com/javase/tutorial/reflect/member/fieldValues.html

How do bind indexed property to jface viewer

I want to bind an indexed property to JFace ComboViewer.
Lets say that I have a DataModel class like this:
class DataModel {
private String[] props = {"A","B","C"};
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public String getProperties( int idx ){
return props[idx];
}
public void setProperties( int idx, String value ){
String oldVal = props[idx];
props[idx] = value;
pcs.fireIndexedPropertyChange( "properties", idx, oldVal, value );
}
// code to add/remove PropertyChangeListener
// ...
}
The data binding code for simple property would look like this:
DataModel dataModel = ...
ComboViewer propertyChoice = ...
DataBindingContext ctx = new DataBindingContext();
IObservableValue target = ViewerProperties.singleSelection().observe( propertyChoice );
IObservableValue model = BeanProperties.value( DataModel.class, "properties" ).observe(dataModel);
ctx.bindValue( target, model );
but with an indexed property I have to inform the ctx at which index is the value that I want to bind. I have tried
IObservableValue model = BeanProperties.value( DataModel.class, "properties[0]" ).observe(dataModel);
but it doesn't work.
Is it possible to bind indexed property instead of simple property? How?
Unfortunately this seems to be unsupported. I was looking for exactly the same functionality. There is no documentation in BeanProperties that says it is supported.
When looking into the implementation of BeanProperties.value, you find that it delegates to BeanPropertyHelper for reading and writing a property. The method Object readProperty(Object source, PropertyDescriptor propertyDescriptor) does not know about the subclass IndexedPropertyDescriptor. When it is invoked for an indexed property, readProperty tries to use a read method that reads the entire array. I think this method is optional for indexed properties. For indexed properties it should use the IndexedPropertyDescriptor.getIndexedReadMethod().
Depending on your use case you may be able to workaround the problem by using BeanProperties.list. However you cannot use this in combination with indexed properties. I tried this by adding a method that returns the entire array but still keeping the method that does a "fireIndexedPropertyChange". Unfortunately this gives a ClassCastException: Eclipse's BeanListProperty seems to suppose that the value in the change event is an array or list. However for an indexed property it is a single element of the array.
Or perhaps you can use an observable map instead?

Categories