it.cnr.iit.jscontact.tools.dto.Card Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jscontact-tools Show documentation
Show all versions of jscontact-tools Show documentation
Java tools for JSContact building, validation, serialization/deserialization and conversion from vCard 4.0 (RFC6350) and its transliterations, namely xCard (RFC6351) and jCard (RFC7095).
/*
* Copyright (C) 2020 Consiglio Nazionale delle Ricerche
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package it.cnr.iit.jscontact.tools.dto;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
import it.cnr.iit.jscontact.tools.constraints.*;
import it.cnr.iit.jscontact.tools.constraints.validators.builder.ValidatorBuilder;
import it.cnr.iit.jscontact.tools.dto.annotations.ContainsExtensibleEnum;
import it.cnr.iit.jscontact.tools.dto.annotations.JSContactCollection;
import it.cnr.iit.jscontact.tools.dto.deserializers.VCardPropsDeserializer;
import it.cnr.iit.jscontact.tools.dto.deserializers.CardKindDeserializer;
import it.cnr.iit.jscontact.tools.dto.interfaces.IsIANAType;
import it.cnr.iit.jscontact.tools.dto.serializers.VCardPropsSerializer;
import it.cnr.iit.jscontact.tools.dto.serializers.UTCDateTimeSerializer;
import it.cnr.iit.jscontact.tools.dto.utils.JsonPointerUtils;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
import java.util.*;
/**
* Class mapping the Card object as defined in section 2 of [draft-ietf-calext-jscontact].
*
* @see draft-ietf-calext-jscontact
* @see draft-ietf-calext-jscontact-vcard
* @author Mario Loffredo
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"@type", "version", "created", "kind", "language", "members", "prodId", "relatedTo", "uid", "updated",
"name", "nicknames", "organizations", "speakToAs", "titles",
"emails", "onlineServices", "phones", "preferredLanguages",
"calendars", "schedulingAddresses",
"addresses",
"cryptoKeys", "directories", "links", "media",
"localizations",
"anniversaries", "keywords", "personalInfo", "notes",
"vCardProps"})
@TitleOrganizationConstraint
@MembersVsCardKindValueConstraint
@LocalizationsConstraint
@NoArgsConstructor
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(of = {"uid"}, callSuper = false)
@SuperBuilder
public class Card extends AbstractExtensibleJSContactType implements IsIANAType, Serializable {
private static ObjectMapper mapper = new ObjectMapper();
/*
Metadata properties
*/
// Section 2.1.1 of [draft-ietf-calext-jscontact]
@NotNull
@Pattern(regexp = "Card", message = "invalid @type value in Card")
@JsonProperty("@type")
@Builder.Default
String _type = "Card";
// Section 2.1.2 of [draft-ietf-calext-jscontact]
@NotNull
@VersionValueConstraint
@Builder.Default
String version = "1.0";
// Section 2.1.3 of [draft-ietf-calext-jscontact]
@JsonSerialize(using = UTCDateTimeSerializer.class)
@JsonDeserialize(using = DateDeserializers.CalendarDeserializer.class)
java.util.Calendar created;
// Section 2.1.4 of [draft-ietf-calext-jscontact]
@JsonDeserialize(using = CardKindDeserializer.class)
@ContainsExtensibleEnum(enumClass = KindEnum.class, getMethod = "getKind")
KindType kind;
// Section 2.1.5 of [draft-ietf-calext-jscontact]
@LanguageTagConstraint
String language;
// Section 2.1.6 of [draft-ietf-calext-jscontact]
@BooleanMapConstraint(message = "invalid Map members in JSContact - Only Boolean.TRUE allowed")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map members;
// Section 2.1.7 of [draft-ietf-calext-jscontact]
String prodId;
// Section 2.1.8 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addRelation", itemClass = Relation.class)
@JsonPropertyOrder(alphabetic = true)
@RelatedToConstraint
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map relatedTo;
// Section 2.1.9 of [draft-ietf-calext-jscontact]
@NotNull(message = "uid is missing in Card")
@NonNull
String uid;
// Section 2.1.10 of [draft-ietf-calext-jscontact]
@JsonSerialize(using = UTCDateTimeSerializer.class)
@JsonDeserialize(using = DateDeserializers.CalendarDeserializer.class)
java.util.Calendar updated;
/*
Name and Organization properties
*/
// Section 2.2.1 of [draft-ietf-calext-jscontact]
@Valid
Name name;
// Section 2.2.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addNickName", itemClass = Nickname.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map nicknames;
// Section 2.2.2 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addOrganization", itemClass = Organization.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map organizations;
// Section 2.2.3 of [draft-ietf-calext-jscontact]
@Valid
SpeakToAs speakToAs;
// Section 2.2.4 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addTitle", itemClass = Title.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map titles;
/*
Contact and Resource properties
*/
// Section 2.3.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addEmailAddress", itemClass = EmailAddress.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map emails;
// Section 2.3.2 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addOnlineService", itemClass = OnlineService.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map onlineServices;
// Section 2.3.3 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addPhone", itemClass = Phone.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map phones;
// Section 2.3.4 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addLanguagePref", itemClass = LanguagePref.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map preferredLanguages;
/*
Calendaring and Scheduling properties
*/
// Section 2.4.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addCalendar", itemClass = Calendar.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map calendars;
// Section 2.4.2 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addSchedulingAddress", itemClass = SchedulingAddress.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map schedulingAddresses;
/*
Address and Location properties
*/
// Section 2.5.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addAddress", itemClass = Address.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map addresses;
/*
Resource properties
*/
// Section 2.6.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addCryptoResource", itemClass = CryptoKey.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map cryptoKeys;
// Section 2.6.2 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addDirectoryResource", itemClass = Directory.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map directories;
// Section 2.6.3 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addLinkResource", itemClass = Link.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map links;
// Section 2.6.4 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addMediaResource", itemClass = Media.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map media;
/*
Multilingual properties
*/
// Section 2.7.1 of [draft-ietf-calext-jscontact]
@JsonPropertyOrder(alphabetic = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map> localizations;
/*
Additional properties
*/
// Section 2.8.1 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addAnniversary", itemClass = Anniversary.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map anniversaries;
// Section 2.8.2 of [draft-ietf-calext-jscontact]
@BooleanMapConstraint(message = "invalid Map keywords in JSContact - Only Boolean.TRUE allowed")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map keywords;
// Section 2.8.3 of [draft-ietf-calext-jscontact]
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map notes;
// Section 2.8.4 of [draft-ietf-calext-jscontact]
@JSContactCollection(addMethod = "addPersonalInfo", itemClass = PersonalInfo.class)
@JsonPropertyOrder(alphabetic = true)
@Valid
@IdMapConstraint(message = "invalid Id in Map")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
Map personalInfo;
// Section 2.15.1 of [draft-ietf-calext-jscontact-vcard]
@JsonProperty("vCardProps")
@JsonSerialize(using = VCardPropsSerializer.class)
@JsonDeserialize(using = VCardPropsDeserializer.class)
@Valid
@JsonInclude(JsonInclude.Include.NON_EMPTY)
VCardProp[] vCardProps;
@JsonIgnore
Map customTimeZones;
@JsonIgnore
@Getter
private List validationMessages;
//Methods for adding items to a mutable collection
/**
* Adds a member to this object.
*
* @param member the uid value of the object representing a group member
*/
public void addMember(String member) {
if(members == null)
members = new LinkedHashMap<>();
members.putIfAbsent(member,Boolean.TRUE);
}
/**
* Adds a relation between this object and another Card object.
*
* @param key the uid value of the related Card object
* @param relType one of the RELATED property [RFC6350] type parameter values, or an IANA-registered value, or a vendor-specific value
* @see RFC6350
*/
public void addRelation(String key, RelationType relType) {
if (relatedTo == null)
relatedTo = new HashMap<>();
Relation relationPerKey = relatedTo.get(key);
if (relationPerKey == null) {
if (relType == null)
relatedTo.put(key, Relation.builder().build());
else
relatedTo.put(key, Relation.builder()
.relation(new HashMap() {{
put(relType, Boolean.TRUE);
}})
.build());
}
else {
if (relType == null)
relatedTo.put(key, Relation.builder().build());
else {
Map map = new HashMap<>(relationPerKey.getRelation());
map.put(relType, Boolean.TRUE);
relatedTo.replace(key, Relation.builder()
.relation(map)
.build());
}
}
}
/**
* Adds a nickname to this object.
*
* @param id the nickname identifier
* @param nickname the object representing the nickname
*/
public void addNickName(String id, Nickname nickname) {
if(nicknames == null)
nicknames = new HashMap<>();
nicknames.putIfAbsent(id,nickname);
}
/**
* Adds an organization to this object.
*
* @param id the organization identifier
* @param organization the object representing the organization
*/
public void addOrganization(String id, Organization organization) {
if(organizations == null)
organizations = new HashMap<>();
organizations.putIfAbsent(id,organization);
}
/**
* Adds a title to this object.
*
* @param id the title identifier
* @param title the object representing the title
*/
public void addTitle(String id, Title title) {
if(titles == null)
titles = new HashMap<>();
titles.putIfAbsent(id,title);
}
/**
* Adds an email address to this object.
*
* @param id the email identifier
* @param email the object representing the email address
*/
public void addEmailAddress(String id, EmailAddress email) {
if (emails == null)
emails = new HashMap<>();
emails.putIfAbsent(id, email);
}
/**
* Adds a scheduling address to this object.
*
* @param id the scheduling address identifier
* @param scheduling the object representing the scheduling address
*/
public void addSchedulingAddress(String id, SchedulingAddress scheduling) {
if (this.schedulingAddresses == null)
this.schedulingAddresses = new HashMap<>();
this.schedulingAddresses.putIfAbsent(id, scheduling);
}
/**
* Adds an online service to this object.
*
* @param id the online service identifier
* @param onlineService the object representing the online service
*/
public void addOnlineService(String id, OnlineService onlineService) {
if (this.onlineServices == null)
this.onlineServices = new HashMap<>();
this.onlineServices.putIfAbsent(id, onlineService);
}
/**
* Adds a phone number to this object.
*
* @param id the phone number identifier
* @param phone the object representing the phone number
*/
public void addPhone(String id, Phone phone) {
if (phones == null)
phones = new HashMap<>();
phones.putIfAbsent(id, phone);
}
/**
* Adds a directory resource to this object.
*
* @param id the directory resource identifier
* @param resource the object representing the directory resource
*/
public void addDirectoryResource(String id, Directory resource) {
if (directories == null)
directories = new HashMap<>();
directories.putIfAbsent(id, resource);
}
/**
* Adds a crypto resource to this object.
*
* @param id the crypto resource identifier
* @param resource the object representing the crypto resource
*/
public void addCryptoResource(String id, CryptoKey resource) {
if (cryptoKeys == null)
cryptoKeys = new HashMap<>();
cryptoKeys.putIfAbsent(id, resource);
}
/**
* Adds a calendar resource to this object.
*
* @param id the calendar resource identifier
* @param resource the object representing the calendar resource
*/
public void addCalendarResource(String id, Calendar resource) {
if (calendars == null)
calendars = new HashMap<>();
calendars.putIfAbsent(id, resource);
}
/**
* Adds a link resource to this object.
*
* @param id the link resource identifier
* @param resource the object representing the link resource
*/
public void addLinkResource(String id, Link resource) {
if (links == null)
links = new HashMap<>();
links.putIfAbsent(id, resource);
}
/**
* Adds a media resource to this object.
*
* @param id the media resource identifier
* @param resource the object representing the media resource
*/
public void addMediaResource(String id, Media resource) {
if (media == null)
media = new HashMap<>();
media.putIfAbsent(id, resource);
}
/**
* Adds a language preference to this object.
*
* @param id the contact language identifier
* @param languagePref the object representing the contact language
*/
public void addLanguagePref(String id, LanguagePref languagePref) {
if (preferredLanguages == null)
preferredLanguages = new HashMap<>();
preferredLanguages.putIfAbsent(id, languagePref);
}
/**
* Adds a delivery address to this object.
*
* @param id the delivery address identifier
* @param address the object representing the delivery address
*/
public void addAddress(String id, Address address) {
if(addresses == null)
addresses = new HashMap<>();
addresses.putIfAbsent(id,address);
}
/**
* Adds an anniversary to this object.
*
* @param id the anniversary identifier
* @param anniversary the object representing the anniversary
*/
public void addAnniversary(String id, Anniversary anniversary) {
if(anniversaries == null)
anniversaries = new HashMap<>();
anniversaries.putIfAbsent(id,anniversary);
}
/**
* Adds personal information to this object.
*
* @param id the personal information identifier
* @param personalInfo the object representing the personal information
*/
public void addPersonalInfo(String id, PersonalInfo personalInfo) {
if (this.personalInfo == null)
this.personalInfo = new HashMap<>();
this.personalInfo.putIfAbsent(id, personalInfo);
}
/**
* Adds a note to this object.
*
* @param id the note identifier
* @param note the note object
*/
public void addNote(String id, Note note) {
if(notes == null)
notes = new HashMap<>();
notes.putIfAbsent(id,note);
}
private void addKeyword(String keyword) {
if(keywords == null)
keywords = new LinkedHashMap<>();
keywords.putIfAbsent(keyword,Boolean.TRUE);
}
/**
* Adds a collection of keywords to this object.
*
* @param keywords the keywords
*/
public void addKeywords(String[] keywords) {
if (keywords==null)
return;
for (String keyword: keywords)
addKeyword(keyword);
}
/**
* Adds a localization to a property of this object.
*
* @param language the localization language tag [RFC5646]
* @param path the JSON pointer [RFC6901] to the property
* @param object the Jackson library JsonNode object representing the localization for the property
* @see RFC5646
* @see RFC6901
* @see Jackson Project Home
*/
public void addLocalization(String language, String path, JsonNode object) {
if (language == null || path == null || object == null)
return;
if (localizations == null)
localizations = new HashMap<>();
Map localizationsPerLanguage;
if (localizations.containsKey(language))
localizationsPerLanguage = localizations.get(language);
else
localizationsPerLanguage = new HashMap<>();
if (localizationsPerLanguage.containsKey(path))
localizationsPerLanguage.replace(path, object);
else
localizationsPerLanguage.put(path, object);
if (localizations.containsKey(language))
localizations.replace(language, localizationsPerLanguage);
else
localizations.put(language, localizationsPerLanguage);
}
/**
* Returns all the localizations of this object for a given property.
*
* @param path the JSON pointer [RFC6901] to the property
* @return a map of language tags [RFC5646] to Jackson library JsonNode objects representing the localizations for the property
* @see RFC5646
* @see RFC6901
* @see Jackson Project Home
*/
@JsonIgnore
public Map getLocalizationsPerPath(String path) {
if (localizations == null)
return null;
Map localizationsPerPath = new HashMap<>();
for (Map.Entry> localizationsPerLang : localizations.entrySet()) {
if (localizationsPerLang.getValue().containsKey(path))
localizationsPerPath.put(localizationsPerLang.getKey(), localizationsPerLang.getValue().get(path));
}
return (localizationsPerPath.size() != 0) ? localizationsPerPath : null;
}
/**
* Returns all the localizations of this object for a given property.
*
* @param language the localization language tag [RFC5646]
* @return a map of JSON pointers [RFC6901] to Jackson library JsonNode objects representing the localizations for the property
* @see RFC5646
* @see RFC6901
* @see Jackson Project Home
*/
@JsonIgnore
public Map getLocalizationsPerLanguage(String language) {
if (localizations == null)
return null;
return localizations.get(language);
}
/**
* Returns the localization to a property of this object for given language and path.
*
* @param language the localization language tag [RFC5646]
* @param path the JSON pointer [RFC6901] to the property
* @return the Jackson library JsonNode object representing the localization for the property
* @see RFC5646
* @see RFC6901
* @see Jackson Project Home
*/
@JsonIgnore
public JsonNode getLocalization(String language, String path) {
if (localizations == null)
return null;
Map localizationsPerPath = getLocalizationsPerPath(path);
if (localizationsPerPath == null)
return null;
return localizationsPerPath.get(language);
}
/**
* Returns the localized version of this object.
*
* @param language the localization language tag [RFC5646]
* @return the localization of this object for the given language
* @see RFC5646
*/
@JsonIgnore
public Card getLocalizedVersion(String language) {
if (localizations == null)
return null;
Map localizationsPerLanguage = getLocalizationsPerLanguage(language);
if (localizationsPerLanguage == null)
return null;
JsonNode root = mapper.valueToTree(this);
for (Map.Entry localization : localizationsPerLanguage.entrySet()) {
JsonPointer jsonPointer = JsonPointer.compile(JsonPointerUtils.toAbsolute(localization.getKey()));
JsonNode localizedNode = localization.getValue();
JsonNode parentNode = root.at(jsonPointer.head());
if (!parentNode.isMissingNode() && parentNode.isObject()) {
ObjectNode parentObjectNode = (ObjectNode) parentNode;
String fieldName = jsonPointer.last().toString();
fieldName = fieldName.replace(Character.toString(JsonPointer.SEPARATOR), StringUtils.EMPTY);
if (parentObjectNode.get(fieldName) != null)
parentObjectNode.set(fieldName, localizedNode);
}
}
Card localizedCard = mapper.convertValue(root, Card.class);
localizedCard.setLanguage(language);
localizedCard.setLocalizations(null);
return localizedCard;
}
/**
* Returns the localization languages of this object.
*
* @return the array of localization languages [RFC5646]
* @see RFC5646
*/
@JsonIgnore
public String[] getLocalizationsLanguages() {
if (localizations == null)
return null;
return localizations.keySet().toArray(new String[0]);
}
/**
* Clones this object.
*
* @return the clone of this Card object
*/
@Override
public Card clone() {
return SerializationUtils.clone(this);
}
public static Card toJSCard(String json) throws JsonProcessingException {
return mapper.readValue(json, Card.class);
}
public static String toJson(Card jsCard) throws JsonProcessingException {
return mapper.writeValueAsString(jsCard);
}
/**
* Deserialize a single Card object or an array of Card objects
*
* @param json the single Card object or the array of Card objects in JSON
* @return an array of Card objects
* @throws JsonProcessingException never thrown
*/
public static Card[] toJSCards(String json) throws JsonProcessingException {
SimpleModule module = new SimpleModule();
mapper.registerModule(module);
try {
return mapper.readValue(json, Card[].class);
} catch(Exception e) {
return new Card[]{mapper.readValue(json, Card.class)};
}
}
/**
* Serialize an array of Card objects
*
* @param jsCards the array of Card objects
* @return the array of Card objects in JSON
* @throws JsonProcessingException never thrown
*/
public static String toJson(Card[] jsCards) throws JsonProcessingException {
return mapper.writeValueAsString(jsCards);
}
/**
* Adds a VCardProp object to this object.
*
* @param o the VCardProp object
*/
public void addVCardProp(VCardProp o) {
vCardProps = ArrayUtils.add(vCardProps, o);
}
/**
* Convert the vCardProps array into a map
* where the keys are the extnsion names and
* the values are the extension values in text format
*
* @return vCardProps array converted into a map
*/
@JsonIgnore
public Map getVCardPropsAsMap() {
Map map = new HashMap<>();
if (this.getVCardProps() == null)
return map;
for (VCardProp jCardExtension : this.getVCardProps())
map.put(jCardExtension.getName().toString(),jCardExtension.getValue().toString());
return map;
}
/**
* Tests if a JSContact Card is valid.
*
* @return true if the validation check ends successfully, false otherwise
*/
@JsonIgnore
public boolean isValid() {
validationMessages = new ArrayList<>();
Set> constraintViolations;
constraintViolations = ValidatorBuilder.getValidator().validate(this);
if (constraintViolations.size() > 0) {
for (ConstraintViolation constraintViolation : constraintViolations)
validationMessages.add(constraintViolation.getMessage());
return false;
}
return true;
}
/**
* Returns the error message when the validation check ends unsuccessfully.
*
* @return the validation message as a text
*/
@JsonIgnore
public String getValidationMessage() {
if (validationMessages == null)
return null;
return String.join("\n", validationMessages);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy