How to get VCard Property "Name" with ezvcard - vcf-vcard

I'm trying to get the "Name" of VCard properties, but I don't see a
"getName()" function. However, the following seems to work. Is it
legitimate to rely upon?
for (VCardProperty property : vCardThis.getProperties()){
String propKeyS = property.toString() ;
int atLoc = propKeyS.indexOf("#") ;
String propName = propKeyS.substring(0, atLoc) ;
System.out.println(propName) ;
}

The name that is assigned to the property when it is serialized is stored in the property's scribe class.
To get a property's scribe class, use the ScribeIndex class like so:
ScribeIndex index = new ScribeIndex();
for (VCardProperty property : vCardThis.getProperties()){
VCardPropertyScribe<? extends VCardProperty> scribe = index.getPropertyScribe(property);
System.out.println(scribe.getPropertyName());
}

Related

Jackson deserialization: How to get a default value even if the JSON property was null

In my project I'm using Jersey 2.23.1 with Jackson for JSON support.
When I'm getting a request with something like { "foo":null, "bar":"123" } as JSON, matching with class A{String foo; String bar;} Jersey first creates and instance of A (with default values if specified in constructor), then deserialize JSON to a temporary object A', then copies all JSON fields that were specified in JSON from A' to A. If I have default values in A-class constructor, and have fields equal to null in JSON, all my default values are erased and replaced by null. So in the example above, if I have a default value for the foo field, it will be replaced by null in the object Jersey will return as param for my #Path annotated method.
I'm using #JsonInclude(Include.NON_NULL) on A class to avoid the transfer of null fields during Response. But it only works for serialization, what about deserialization? I mean, when having { "foo":null } as JSON results in field "foo" = null in new object instance after deserialization.
Here is some code to sum all of this :
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(value = Include.NON_NULL)
public class User {
public enum EUserRole {
PARENT, STUDENT, PROF, ADMIN
}
#Id
public String id;
public String firstName;
public String lastName;
public EUserRole role;
public User() {
id = ObjectId.get().toString();
role = EUserRole.STUDENT;
lastName = "RandomLastName";
}
}
if I'm passing this kind of JSON
{
"id":null,
"lastName":null,
"firstName":"Random First Name",
"role":"STUDENT"
}
to my method (in controller)
#POST
public Response createUser(final User entity) {
}
it results that all null fields in JSON are set to null in my entity and not set to the constructor default values.
Do you know if there is a way to specify Jackson to ignore null fields during deserialization? Or is this a Jersey-related behavior?
There is no way to ignore data from JSON payload in that sense, based on value contained (you can use ignoral to just ignore all values for given property).
So if you want to avoid null assignment, you need define a setter that will just swallow null value (that is, only assign non-null).
Ability to prevent null assignment might a useful feature to add via #JsonFormat.Feature, something like:
// hypothetical no such feature exists yes
#JsonFormat(without = JsonFormat.Feature.ALLOW_NULL_ASSIGNMENT)
so perhaps this could be a feature request.
And the reason I think this belongs to per-property handling is that this seems like a specific rule for some of the properties. Although perhaps there could also be a matching global setting if it seems users really like such null-ignoral.

Assign Jackson-Jsog's #id to a member variable

Is it possible to assign the jsog's #id value to an member variable in a POJO class?
For example I have a json:
"user": {
"#id": "1",
"name": "John Doe"
}
And Java class
#JsonIdentityInfo(generator=JSOGGenerator.class)
public class User {
private String id; // this is null
private String name;
// getters and setters ...
}
I tried #JsonProperty("#id") but it my id still is null. Does anyone have an experience with this? I don't want to add another id field into my JSON as it makes it ugly.
Thank you in advance.
The identifier "#id" is not a valid Java property since it begins the '#' character. This is a nice feature since it won't conflict with any properties you have on your object.
I'm not sure how you transform that property into a Java property but you probably don't want to. The #id is purely for serialization/deserialization of the object graph; the #id value may change with each serialization if the object graph has changed.
You can't use the #id as an identifier of a object in a meaningful way outside of the serialization. You probably want a real ID that doesn't change based on serialization.

An attribute argument must be a constant expression , typeof expression or array creation expression of an attribute parameter type

I want to assign Group name as an attribute for authorize filter.
It will take as below
[FilterConfig.AuthorizeAd(Group = "DirectoryName")]
public ActionResult GetData()
{
}
Insted of hardcoding i tried by adding it as below
[FilterConfig.AuthorizeAd(Group = Constants.ActiveDirectoryName)]
Where Constants is class and created member as below:
public const string ActiveDirectoryName = "directoryName";
Now i want to aceess it from app.config, tried as below
[FilterConfig.AuthorizeAd(Group = ConfigurationManager.AppSettings["Directory_Name"].ToString()
It is throughing the error msg as "An attribute argument must be a constant expression"
How can i assign the data from config?
Please suggest me.
You can't do that with attributes, they have to be constants as stated in the error message. If you wanted to get a value from the configuration file, you could do it by passing the key to the attribute, and then in the constructor get the value you want from the configurationmanager
public MyAttribute :Attribute
{
private string _config;
public MyAttribute(string configKey)
{
_config = ConfigurationManager.AppSettings[configKey];
...
}
}
HTH

What is the difference between NoSetter and ReadOnly?

What is the difference between NoSetter and ReadOnly?
NHibernate defines the following enum:
namespace NHibernate.Mapping.ByCode
{
public enum Accessor
{
Property = 0,
Field = 1,
NoSetter = 2,
ReadOnly = 3,
None = 4,
}
}
The docs say this about NoSetter, but fail to mention ReadOnly:
NHibernate will access the field directly when setting the value and will use the Property when getting the value. This can be used when a property only exposes a get accessor because the consumers of your API can't change the value directly. A naming strategy is required because NHibernate uses the value of the name attribute as the property name and needs to be told what the name of the field is.
http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-property
Read only property accessor for persisting calculated properties that don't provide a set method or a backing field.
The calculated value can then be used for querying purposes but it is not read back into the domain.
Source: link

WCF Read DataMember Name attribute

I have a very simple class called person.
public class Person{
[DataMember(Name="MyName")]
public string Name { get;set;}
}
If I try to serialize or de-serialize, everything works great. In the XML I can see a tag called "MyName" and in the object I see with the VS Intellisense a property called Name.
What I need now is to access, from the object, the serialized name of the property.
For example, I can do object.GetType().GetProperty("Name"); but if I try to do object.GetType().GetProperty("MyName"), the reflection says that the property does not exist. How I can read the serialized name of the property? Is there a way?
It seems that the only way is to access, using reflection, the attributes of the property in this way:
var att = myProperty.GetType().GetAttributes();
var attribute = property.GetCustomAttributes(false)[0] as DataMemberAttribute;
Console.WriteLine(attribute.Name);
This works on both, client and server, without the need of serialize and deserialize the object.