Use of Wrapper class for deserialization in callout? - salesforce

I found the following use of a wrapper class, and was wondering if it is a good practice or whether its just duplication of code for no reason.
//Class:
public class SomeClass{
public Integer someInt;
public String someString;
}
//Callout Class:
public class CalloutClass{
public SomeClass someMethod(){
//...code to do a callout to an api
SomeClass someClassObj = (SomeClass)JSON.Deserialize(APIResponse.getBody(), SomeClass.class);
return someClassObj;
}
}
//Controller:
public class SomeController {
public SomeController(){
someClassObj = calloutClassObj.someMethod();
SomeWrapper wrapperObj = new SomeWrapper();
for(SomeClass iterObj : someClassObj){
wrapperObj.someWrapperInt = iterObj.someInt;
wrapperObj.someWrapperString = iterObj.someString;
}
}
public class someWrapper{
public Integer someWrapperInt{get;set;}
public String someWrapperString{get;set;}
}
}
The wrapper class "someWrapper" could be eliminated if we just use getters and setters ({get;set;}) in "SomeClass."
Could anyone explain if there could be a reason for following this procedure?
Thanks,
James

My assumption (because, code in controller is extra pseudo) is
SomeClass is a business entity, purpose of which is to store/work with business data. By work I mean using it's values to display it (using wrapper in controller), to calculate smth in other entities or build reports... Such kind of object should be as lightweight as possible. You usually iterate through them. You don't need any methods in such kind of objects. Exception is constructor with parameter(s). You might want to have SomeObject__c as parameter or someWrapper.
someWrapper is a entity to display business entity. As for wrapper classes in controllers. Imagine, that when you display entity on edit page and enter a value for someWrapperInt property, you want to update someWrapperString property (or you can just put validation there, for example, checking if it is really Integer). Usually, as for business entity, you don't want such kind of functionality. But when user create or edit it, you may want smth like this.

Related

How to include a nested PropertyBusinessObject in a PropertyBusinessObject json?

My app contains several PropertyBusinessObject entities, and most of them have nested PropertyBusinessObject objects as properties.
For instance, a Note has a parent User which had written the note, so the Note entity contain a Property<User, Note> which is instantiated with the User.class and the name of the property.
Here is the code of the Note Entity:
public class Note extends AbstractEntity
{
public final Property<User, Note> author = new Property<>("author", User.class);
public final Property<String, TarotNote> text = new Property<>("text");
public Note() {}
}
AbstractEntity implements the PropertyBusiness interface and define the methods to be overridden by the entities to properly implements the interface.
And here is the result JSON from PropertyIndex.toJson:
{
"author": "our.app.backend.entity.User#77203809",
"text": "test"
}
Do I need to override the toString method of all my entities to be sure to not have this behavior (seems to be the wrong way...) ? Or (I hope) is there another way?
For your information, the parsing of the Json issued from the server works perfectly fine with nested entities.
This seems like a logic bug in the JSON generation code, I've added code to fix this here: https://github.com/codenameone/CodenameOne/commit/34447f62971d8bb696116f02c97bac9b70de89b6

How to know what class is being deserialized in JackSon Deserializer?

I'm using app engine datastore so I have entity like this.
#PersistenceCapable
public class Author {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
#JsonProperty("id")
#JsonSerialize(using = JsonKeySerializer.class)
#JsonDeserialize(using = JsonKeyDeserializer.class)
private Key key;
....
}
When the model is sent to view, it will serialize the Key object as an Id value. Then, if I send data back from view I want to deserialize the Id back to Key object by using JsonKeyDeserializer class.
public class JsonKeyDeserializer extends JsonDeserializer<Key> {
#Override
public Key deserialize(JsonParser jsonParser, DeserializationContext deserializeContext)
throws IOException, JsonProcessingException {
String id = jsonParser.getText();
if (id.isEmpty()) {
return null;
}
// Here is the problem because I have several entities and I can't fix the Author class in this deserializer like this.
// I want to know what class is being deserialized at runtime.
// return KeyFactory.createKey(Author.class.getSimpleName(), Integer.parseInt(id))
}
}
I tried to debug the value in deserialize's parameters but I can't find the way to get the target deserialized class. How can I solve this?
You may have misunderstood the role of KeySerializer/KeyDeserializer: they are used for Java Map keys, and not as generic identifiers in database sense of term "key".
So you probably would need to use regular JsonSerializer/JsonDeserializer instead.
As to type: it is assumed that handlers are constructed for specific types, and no extra type information is passed during serialization or deserialization process: expected type (if handlers are used for different types) must be passed during construction.
When registering general serializers or deserializers, you can do this when implementing Module, as one of the arguments is type for which (de)serializer is requested.
When defining handlers directly for properties (like when using annotations), this information is available on createContextual() callback of interface ContextualSerializer (and -Deserializer), if your handler implements it: BeanProperty is passed to specify property (in this case field with annotation), and you can access its type. This information needs to be stored to be used during (de)serialization.
EDIT: as author pointed out, I actually misread the question: KeySerializer is the class name, not annotation.

Importing a class with a specific parameter

I got a ViewModel which I export with MEF. I'd like this ViewModel to be initialized differently each time it's being imported, according to an enum/specific object parameter that will be provided to it.
I've been reading a little on the subject and I found that maybe this -
http://msdn.microsoft.com/en-us/library/ee155691.aspx#metadata_and_metadata_views
would be able to fit my needs, but I'm not sure that this would be the best way to do it.
Another method I've been thinking about is importing the class normally, and then once I've an instance, to call a special initialization method that would receive my parameter. However this doesn't seem like a classic MEF implementation, and maybe losses some of its "magic".
I'm hoping someone would be able to point out for me what would be the recommended method to achieve this.
Thanks!
A workaround is exporting a factory that creates instances of your type. While this means you cannot directly import thos instances, it does have the benefit that the logic to create them is the responsability of the factory so users of the class do not have to know about it:
public class ServiceWithParameter
{
public ServiceWithParameter( int a )
{
this.a = a;
}
private readonly int a;
}
[Export]
public class ServiceWithParameterFactory
{
public ServiceWithParameterFactory()
{
instance = 0;
}
public ServiceWithParameter Instance()
{
return new ServiceWithParameter( instance++ );
}
private int instance;
}
//now everywhere you need ServiceWithParameter:
[Import]
ServiceWithParameterFactory serviceFactory;
var instanceA = serviceFactory.Instance(); //instanceA.a = 0
var instanceB = serviceFactory.Instance(); //instanceB.a = 1
A more extensible way is telling the container you have a factory and an example is presented here: http://pwlodek.blogspot.com/2010/10/mef-object-factories-using-export.html

Data annotation and wpf validation

Is there any way that I use data annotation as the source of validation in WPF? I want to be able to define a class such as:
class myData
{
[Required]
[MaxLength(50)]
public string Name{get;set;}
}
And then bind it to a field in a view and the wpf validate that user enter some value for this field and also make sure that its length is not greater than 50. I know that I can write a validator for this, but then if I change the maxLength to say 60, then I need to change it in validator and I don't want to have changes in different places.
You need to create a "metadata" definition of the class. You'll need something like this:
[MetadataTypeAttribute(typeof(MyClass.MyClassMetadata))]
public partial class MyClass
{
internal sealed class MyClassMetadata
{
// Metadata classes are not meant to be instantiated.
private MyClassMetadata()
{
}
[Required]
[MaxLength(50)]
public string Name{ get; set; }
}
}
This extends the class with the necessary meta data to support the validation.
Since this question is still left unanswered and I came across it while answering another question that was looking for the same thing, I would share the solution of that question over here too.
The Microsoft TechNet article "Data Validation in MVVM" is a very clean and thorough implementation of using Data Annotations for validation in WPF. I read through the solution myself and would recommend it to others.

How to write a commom class for two ViewModel classes?

I have two viewmodel classes called ChangePwdViewModel.cs and ExpiringPwdViewModel.cs.
ChangPwd.xaml binds to ChangePwdViewModel and ExpiringPwd.xaml binds to ExpiringPwdViewModel.
Both have the property as below.
private string _message;
public string Message
{
get { return _message; }
set { _message = value; OnPropertyChanged("Message"); }
}
In each class, there's a function called ValidatePwd() to validate the new password.
In this function, Message property is updated.
Eg.
if (IsAlphaNumeric(this.NewPassword) == false || IsAlphaNumeric(this.CfmPassword) == false)
{
this.Message = "Invalid new password, only characters and numbers are accepted, password must contain at least one character and one number";
this.ResetPasswordFields();
return false;
}
I want to create a common class to write this function and used by two viewmodel. But, How can I update the Message Property of the viewmodels from this class?
How about putting it in a base class:
class ViewModelBase
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; OnPropertyChanged("Message"); }
}
public bool VerifyPassword(string newPassword)
{
....
}
}
class ChangePwdViewModel : ViewModelBase
{
}
class ExpiringPwdViewModel : ViewModelBase
{
}
Update:
If you can't use a base class because your view models already have a base class then you could use an interface as suggested by others. However this means that you will still have to implement the interface in all your view model classes so you don't gain that much in terms of avoiding multiple implementations (except that you have a contract for your view models then which is usually a good thing to have).
You can achieve some kind of "multiple inheritance" in C# by using a tool like Dynamic Proxy which allows you to create mixins. So you could implement the Message property and password verification in one class and then create a mixin proxy which merges the view model with that implementation. It's not as nice as you will have to create all your view model instances via the proxy generator but it can be made to work. Have a look at this tutorial if it sounds like an option for you.
You could have the two ViewModel classes implement a common interface, say IMessage that implemented a single property - Message.
Then your common class or a function would take a parameter of type IMessage that it could use to update the message.
I would suggest to avoid base classes (could cause potential design issues in future) in such cases, I would rather suggest to pass through constructor an algorithm of validation, smth like this:
public class MyViewModel
{
public MyViewModel(Func<bool> validationAlgorithm)
{
// ... save function to use later for a validation
}
}

Resources