Wicket: Is using PropertyResolver ok? - java

I have an object and in several components I need to render two of its properties concatenated together with a delimiter. If one of the properties is null then it should not display the delimiter but just the not null property. If both are null then it should not display at all.
The two properties are accessed thus:
thing.getFoo()
and
thing.getStuff().getBar()
The renderer will be a class with one static method taking an instance of the type of thing and will return a string.
The problem is that it seems ugly to do so much null checking on thing and the result of thing.getStuff() so I was wondering if to use PropertyResolver instead.
The problem is that the Javadoc says it's not part of the Wicket API and to only use it if I know what I'm doing. I presume therefore that there are certain caveats or issues that I should know about? If so, what are they?

I would use a custom read only model in that case. Something like:
private static class ConcatenatingPropertyModel extends AbstractReadOnlyModel<String> {
private List<PropertyModel<String>> models = new ArrayList<PropertyModel<String>>();
public ConcatenatingPropertyModel(Object object, String... props) {
for (String prop : props) {
models.add(new PropertyModel<String>(object, prop));
}
}
#Override
public String getObject() {
// iterate over delegate property models and concatenate
}
#Override
public void detach() {
super.detach();
for (PropertyModel<String> model : models) {
model.detach();
}
}
}
Then you can use the model like this:
new ConcatenatingPropertyModel(thing, "foo", "stuff.bar");

Related

Using a value of the enum to serialize with Gson

I have two enums I've created for my Java project, and both of them need to be serialized and deserialized using Gson. The problem is, I need to use a value on each enum Field as the serialized value.
As an example, I have these enums:
Options Enum
Language Enum
My hope is that I am able to serialize both enums using the key value provided to both. This is a really simplified example, but it still perfectly describes my situation.
I tried using custom serializer classes for both:
Options Serializer
Language Serializer
And yes, I did register both using registerTypeAdapter(type, adapter)
The strange this is, it would work for one enum, serializing to the correct value, but not the other. I suspect it's because the class that's being serialized is formatted similar to this:
public class Item {
public Language language;
public List<Options> options;
}
Where in this case, Language is serialized properly, but the Options enum is not, just returning the enum value name.
I'm not sure if there's some special way I need to handle this, but it's getting frustrating.
EDIT: I know about using the #SerializedName() annotation, but both of the enums I'm using have hundreds of entries and the keys that are part of the enum are used elsewhere throughout the program as well. Using #SerializedName(), at least in my case, I don't think would be feasible.
Write an adapter for Item. I would add more but laptop on 1%.
static class ItemAdapter extends TypeAdapter<Item> {
#Override
public void write(JsonWriter out, Item value) throws IOException {
out.beginObject();
out.name("language").value(value.language.key);
out.name("options");
out.beginArray();
for (Option option : value.options) {
out.value(option.key);
}
out.endArray();
out.endObject();
}
#Override
public Item read(JsonReader in) throws IOException {
in.beginObject();
in.nextName();
String languageKey = in.nextString();
in.nextName();
in.beginArray();
List<String> optionKeys = new ArrayList<>();
while (in.hasNext()) {
optionKeys.add(in.nextString());
}
in.endArray();
in.endObject();
return new Item(Language.BY_KEY.get(languageKey),
optionKeys.stream()
.map(Option.BY_KEY::get)
.collect(Collectors.toList()));
}
}

Iterate Fields of Fields continuously with reflection

Please avoid giving answers in Kotlin only and higher than Android 21.
I'm trying to build an API parser that makes use of class hierarchy logic to represent the API hierarchy itself. With this structure I am able to parse the API in an uncomplicated fashion and I was able to achieve this already, but I'd like to improve it further.
I'll begin explaining what I already have implemented.
This is an example URL that my app will receive via GET, parse and dispatch internally:
http://www.example.com/news/article/1105
In the app the base domain is irrelevant, but what comes after is the API structure.
In this case we have a mixture of commands and variables:
news (command)
article (command)
1105 (variable)
To establish what is a command and what is a variable I built the following class structures:
public class API {
public static final News extends AbstractNews {}
}
public class AbstractNews {
public static final Article extends AbstractArticle {}
}
public class Article {
public static void GET(String articleId) {
// ...
}
}
And I iterate through each class after splitting the URL while matching each command to each class (or subclass) starting from the API class. Until I reach the end of the split URL any matches that fail are stored in a separate list as variables.
The process is as follows for the example provided above:
Split URL each forward slash (ignoring the base domain)
/news/article/1105
List<String> stringList = [
news,
article,
1105
];
Iterate each item in the split list and match agains the API structured classes (the following is just a sample example, it is not 100% of what I currently have implemtend):
List<String> variableList = new ArrayList<>();
Class lastClass = API.class;
for (String stringItem : stringList) {
if ((lastClass = classHasSubClass(lastClass, stringItem)) != null) {
continue;
}
variableList.add(stringItem);
}
Once the end of the list is reached I check if the last class contains the request method (in this case GET) and invoke along with the variable list.
Like I said before this is working perfectly fine, but it leaves every class directly exposed and as a result they can be accessed directly and incorrectly by anyone else working on the project, so I am trying to make the hierarchy more contained.
I want to keep the ability to access the methods via hierarchy as well, so the following can still be possible:
API.News.Article.GET(42334);
While at the same time I don't want it to be possible to do the following as well:
AbstractArticle.GET(42334);
I have tried making each subclass into a class instance field instead
public class API {
// this one is static on purpose to avoid having to instantiate
// the API class before accessing its fields
public static final AbstractNews News = new AbstractNews();
}
public class AbstractNews {
public final AbstractArticle Article = new AbstractArticle();
}
public class Article {
public void GET(String articleId) {
// ...
}
}
This works well for the two points I wanted to achieve before, however I am not able to find a way to iterate the class fields in a way that allows me to invoke the final methods correctly.
For the previous logic all I needed to iterate was the following:
private static Class classHasSubClass(Class<?> currentClass, String fieldName) {
Class[] classes;
classes = currentClass.getClasses();
for (final Class classItem : classes) {
if (classItem.getSimpleName().toLowerCase().equals(fieldName)) {
return classItem;
}
}
return null;
}
But for the second logic attempt with fields I was not able to invoke the final method correctly, probably because the resulting logic was in fact trying to do the following:
AbstractArticle.GET(42334);
Instead of
API.News.Article.GET(42334);
I suspect it is because the first parameter of the invoke method can no longer be null like I was doing before and has to be the correct equivalent of API.News.Article.GET(42334);
Is there a way to make this work or is there a better/different way of doing this?
I discovered that I was on the right path with the instance fields, but was missing part of the necessary information to invoke the method correctly at the end.
When iterating the fields I was only using the Class of each field, which was working perfectly fine before with the static class references since those weren't instances, but now it requires the instance of the field in order to work correctly.
In the end the iterating method used in place of classHasSubClass that got this to work is as follows:
private static Object getFieldClass(Class<?> currentClass, Object currentObject, final String fieldName) {
Field[] fieldList;
fieldList = currentClass.getDeclaredFields();
for (final Field field : fieldList) {
if (field.getName().toLowerCase().equals(fieldName)) {
try {
return field.get(currentObject);
} catch (IllegalAccessException e) {
e.printStackTrace();
break;
}
}
}
return null;
}
With this I always keep an instance object reference to the final field that I want to invoke to pass as the 1st parameter (someMethod.invoke(objectInstance);) instead of null.

refreshable javafx ReadOnlyProperty

Say that i have a boolean property that should represent the fact that a specific file inside a specific path exists or not.
Here is some code:
class SomeClass {
protected static final File FILE_TO_TEST = new File("test.canc.me");
//My javafx property
public ReadOnlyBooleanPropertyBase fileExistingProperty = new ReadOnlyBooleanPropertyBase() {
#Override public boolean get() {
return FILE_TO_TEST.exists();
}
#Override public Object getBean() { return null; }
#Override public String getName() { return ""; }
};
//old style property property
public boolean isFileExisting() {
return fileExistingProperty.get();
}
Ok. The fact is that this property is read only since it cannot be set, its value depends of the "external" condition represented by the file to be existent in the application home.
Yet, i need to refresh the property, that is look again to see if the file still exsist or not, and raise change and invalidation events accordingly.
I could easily add a refresh method to the property class, but in order to call it, i would have to create an inner class and not just an anonyous one.
And i would need an anonymous class for each different type of read-only-yet-refreshable property, that is boolean, String, Integer etc.
The question is: is there a more convenient way to accomplish this?
i would have to create an inner class and not just an anonyous one.
I would go down this approach rather than try to create a bunch of anonymous inner classes.
And i would need an anonymous class for each different type of read-only-yet-refreshable property, that is boolean, String, Integer etc.
Use generics - that's what they're designed for! Create a ReadOnlyRefreshableProperty<T>, then the return types and parameters of the relevant methods all use T as their type, removing the need for a separate class for each type.

General Java class design for property with Collection which needs to listen for change

All,
Hopefully a simple question. I am thinking of the best way to implement a class which holds a number of collections and HashMaps where the class needs to know about when they have been modified outside of the class - i.e. added/removed/changed items. Each collection/hashmap needs to be exposed as a public getter in my class at the moment.
So my basic class looks like as follows...
public class MyClass {
protected final HashMap<String, String> _values = new HashMap<String, String>();
protected final ArrayList<MyOtherClass> _other = new ArrayList<MyOtherClass>();
protected final ArrayList<MyOtherClass2> _other2 = new ArrayList<MyOtherClass2>();
// ... implementation
public HashMap<String, String> getValues() {
return _values;
}
public ArrayList<MyOtherClass> getMyOtherClassList() {
return _other;
}
public ArrayList<MyOtherClass2> getMyOtherClassList2() {
return _other2;
}
public String getContent() {
// build the content based on other/other2...
StringBuilder sb = new StringBuilder();
// iterate through both collections to build content...
// ...
return sb.toString();
}
}
public getMyOtherClass {
public String name; // has getter and setter
public String value; // has getter and setter
}
public getMyOtherClass2 {
public String name; // has getter and setter
public String value; // has getter and setter
public String somethingElse; // has getter and setter
}
I want to add a key/value to the _values based on the length of the content i.e.-
_values.add("Length", getContent().length);
So the Length value is dynamic based on what gets added to the _other and _other2.
The problem with this is exposing the _values and _other with public getters is that anything outside the class can modify them. The class will not know if items have been modified.
A couple of solutions I can think of is to make the collection/hashmap readonly - but this throws a runtime exception - if this was the case I'd like the compiler to indicate that they are read-only and throw an exception but I don't know if this is possible.
The other way would be to add a add/remove for each of the collections/maps and update the Length property accordingly - but again, if the values change in the MyOtherClass, MyClass will still not know about it.
Alternatively write my own Hashmap/List/Collection to determine when items are added/removed, and possibly have a property change listener on the getMyOtherClass, getMyOtherClass2.
Any nice solutions to this?
Thanks,
Andez
Overide the map/list implementations and insert a call-back into the add/update/remove methods that triggers an update function on the parent.
Also it's bad form to create references directly to the implementations - this is better (read up on polymorphism for reasoning):
private Map<String,String> myMap = new HashMap<String,String>();
private List<String> myList = new List<String>();
In this case you can make use of some fundamentals of the Observer design pattern to have an Object "watching" the Maps and registering each change is made to them.
Create an object contains a Map and another object that contains a List, so since you have 1 map and 2 lists you'll have 3 of those "Observable" objects. Let's name the classes "ObservableMap" and "ObservableList". You can even create an abstract class "ObservableObject" and extend it with the previously mentioned classes.
These objects won't override the Map/List implementation, they'll only act as a wrapper by wrapping the methods you'll want to track to register the state and derive the call to modify the collection. For example, I'll post some code of the ObservableMap class (I'm instantiating the map with <String,String> but you can use generics here too if it suits you).
public Class ObservableMap extends ObservableObject{
private Map<String,String> map = new LinkedHashMap<String,String>();
private Watcher observer = new Watcher();
//Example of one of the wrapper methods (the other ones are like this one)
public void putObject(String key, String value) {
watcher.notifyPut(); //You can name the method the way you like and even pass
//the new key/value pair to identify what has been added.
map.put(key,value);
}
}
Here, the Watcher class is the one that registers the canges. It can either be a completely new Object (like in this case) or you can make an Interface and implement it in an existing class of yours to be able to set it as a watcher on your Observable objects.
Not 100% sure what you are asking. If you are trying to track changes to attributes to two classes you may wish, as other people have mentioned implement the observer pattern and raise notifications in the set methods. An alternative, that I have used successfully for implementing an undo mechanism is to use aspectJ or some other AOP (Aspect Orientated Programming) tool to intercept the set methods and perform the required notifications/updates that way.
Alternatively define an interface that only provides access to the getXXX operations and return those from your model, that way nothing can change the data.

How to make this part of code scalable,

There is a part in my java code where I am extending a class from a library which I haven't written.
#override
public Object getPropertyValue(Object id) {
if(id.equals(model.PROPERTY_RENAME))
model.setName((String)value);
else if(id.equals(model.PROPERTY_COLOUR))
model.setColor((Color)value);
}
Now in this case how should I modify this code to make it scalable. There would be many more properties like location, dimension, etc. Now this model is instance of an abstract class AbsModel.
So every class implementing the AbsModel would have different properties. So the class architecture should be there, so that this part of code remains unchanged, no matter how many more model classes I add.
It looks like you want to carry out some operation on the model when this method (getPropertyValue) is called. I would create a Map of id onto the interface ModelOperation defined as follows:
public interface ModelOperation {
void operate(Object value);
}
Then the map would be defines as follows:
map.put(model.PROPERTY_RENAME, new RenameOperation(model));
Your extension class would then look like this:
#Override
public Object getPropertyValue(Object id) {
map.get(id).operate(model);
// etc...
}
For example, RenameOperation would be defined like this:
public class RenameOperation implements ModelOperation {
public RenameOperation(Model model) {
// etc...
}
public void operate(Object value) {
model.setName((String)value);
}
}
This allows you to support as many model operations as you like and means you don't have to change the extension class you have to write. The above is just an outline. You could use generics on the ModelOperation implementations to avoid the cast of the value in each one.
I guess reflection is probably the answer here if you can rely on some naming to help direct you.
It's not going to be nice, but the idea would be that you'd have a method that would reflect on the type and look up the appropriate method. The code belwo
public Object setPropertyValue(Object id) {
String className = id.getClass().getSimpleName();
// Hope that the method is called set<CLASS> and takes a single parameter that is the class
Method method = model.class.getMethod("set" + className, id.getClass());
// Invoke the method (TODO deal with all of the exceptions)
method.invoke(model, id);
}
There are multiple ways of doing this -- though it depends on what do you mean by "scalable" (being able to cope with lots of requests per second or being able to cope with lots of properties?):
one way -- if you're going to go down the path you have outlined in your code is to have those properties that are used very often at the top of your if/then/else block -- so their execution path is very short. this would "scale up" well for lots of requests as not too much time is being spent in actually executing the method (in most cases at least!)
another way -- and this scales up well for lots of properties and easiness of maintaining the code but you will take a hit on execution time: have a Map that maps property names to setxxx() method names, then you can use reflection to invoke these methods on the target object (id in your case) on each call. Classes extended your class will only have to provide a getMap() method which will return the mapping name-to-setter method, which can be a static member and initialized on class load.
Store your properties in a Map -- in which case setName() is the same as map.put( PROPERTY_RENAME, value)
Since in Java functions are not first class citizens, the "nice" route would be very awkward: define an enum with one value per each constant above (i.e. for each property), and a virtual method e.g. update(Object value, then override the method in each enum to update the corresponding property. If you can, redefine the constants PROPERTY_RENAME etc. themselves as enums. This still results in code bloat.
The other way is to use reflection. If you can use the same ids as the property names you want to update, you only need to invoke the setter for the property (as illustrated in other answers). Otherwise you may need to introduce a mapping from ids to property names.
A version not using reflection, call the base class's implementation:
public Object getValue(Object id) {
Object ret = super.getValue(id);
if (ret == null) {
// Subclass specific properties
}
return ret;
}
A common way around this is to use reflection like
public Object getValue(IdType id) {
Method getter = model.getClass().getMethod("get" + id);
return getter.invoke(model); // throws Exceptions.
}
OR
public void setValue(IdType id, Object value) {
Method setter = model.getClass().getMethod("set" + id, value.getClass());
setter.invoke(model, value); // throws Exceptions.
}
I solved this issue by creating an interface. So the code is.
public interface IModel
{
public void setProperty(String propertyName);
}
Rest of the classes were
public class HelloModel implements IModel
{
public void setProperty(String propertyName)
{ code for handling the properties goes here ... }
}
So in this case every class has to handle it's own property setters.
Is this the best way to handle abstraction ? I think this model is very scalable ...

Categories

Resources