Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
5a63537374
commit
dfe0b7ad53
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
namespace WPCordovaClassLib.Cordova.Commands
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Phone.UserData;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Implements helper functionality to serialize contact to JSON string.
|
||||
/// </summary>
|
||||
internal static class ContactsHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts Contact object to string representation
|
||||
/// </summary>
|
||||
/// <param name="contact">Contact object</param>
|
||||
/// <param name="desiredFields">array of fields names</param>
|
||||
/// <returns>JSON string</returns>
|
||||
public static string ToJson(this Contact contact, string[] desiredFields)
|
||||
{
|
||||
var contactFieldsWithJsonVals = contact.PopulateContactDictionary();
|
||||
|
||||
// if desiredFields are not defined, use all avilable fields
|
||||
if (desiredFields == null || desiredFields.Length == 0)
|
||||
{
|
||||
desiredFields = contactFieldsWithJsonVals.Keys.ToArray();
|
||||
}
|
||||
|
||||
return FillResultWithFields(desiredFields, contactFieldsWithJsonVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns JSON string with desired fields only.
|
||||
/// </summary>
|
||||
/// <param name="desiredFields">The desired fields.</param>
|
||||
/// <param name="contactFieldsWithJsonVals">The contact fields with JSON values.</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FillResultWithFields(string[] desiredFields, Dictionary<string, Func<string>> contactFieldsWithJsonVals)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
for (int i = 0; i < desiredFields.Count(); i++)
|
||||
{
|
||||
if (!contactFieldsWithJsonVals.ContainsKey(desiredFields[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Append(contactFieldsWithJsonVals[desiredFields[i]]());
|
||||
if (i != desiredFields.Count() - 1)
|
||||
{
|
||||
result.Append(",");
|
||||
}
|
||||
}
|
||||
|
||||
return "{" + result + "}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the contact dictionary.
|
||||
/// </summary>
|
||||
/// <param name="contact">Contact, that converted to JSON</param>
|
||||
/// <returns>JSON string with populated data</returns>
|
||||
private static Dictionary<string, Func<string>> PopulateContactDictionary(this Contact contact)
|
||||
{
|
||||
var contactFieldsJsonValsDictionary = new Dictionary<string, Func<string>>(StringComparer.InvariantCultureIgnoreCase)
|
||||
{
|
||||
{ "id", () => string.Format("\"id\":\"{0}\"", contact.GetHashCode()) },
|
||||
{ "displayName", () => string.Format("\"displayName\":\"{0}\"", EscapeJson(contact.DisplayName)) },
|
||||
{
|
||||
"nickname",
|
||||
() =>
|
||||
string.Format(
|
||||
"\"nickname\":\"{0}\"",
|
||||
EscapeJson(contact.CompleteName != null ? contact.CompleteName.Nickname : string.Empty))
|
||||
},
|
||||
{ "phoneNumbers", () => string.Format("\"phoneNumbers\":[{0}]", FormatJsonPhoneNumbers(contact)) },
|
||||
{ "emails", () => string.Format("\"emails\":[{0}]", FormatJsonEmails(contact)) },
|
||||
{ "addresses", () => string.Format("\"addresses\":[{0}]", FormatJsonAddresses(contact)) },
|
||||
{ "urls", () => string.Format("\"urls\":[{0}]", FormatJsonWebsites(contact)) },
|
||||
{ "photos", () => string.Format("\"photos\":[{0}]", FormatJsonPhotos(contact)) },
|
||||
{ "name", () => string.Format("\"name\":{0}", FormatJsonName(contact)) },
|
||||
{ "note", () => string.Format("\"note\":\"{0}\"", EscapeJson(contact.Notes.FirstOrDefault())) },
|
||||
{
|
||||
"birthday",
|
||||
() =>
|
||||
string.Format(
|
||||
"\"birthday\":\"{0}\"",
|
||||
EscapeJson(Convert.ToString(contact.Birthdays.FirstOrDefault())))
|
||||
}
|
||||
};
|
||||
return contactFieldsJsonValsDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add escape characters to the JSON string.
|
||||
/// </summary>
|
||||
/// <param name="str">Input JSON formatted string</param>
|
||||
/// <returns>Escaped JSON string</returns>
|
||||
private static string EscapeJson(string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.Replace("\n", "\\n")
|
||||
.Replace("\r", "\\r")
|
||||
.Replace("\t", "\\t")
|
||||
.Replace("\"", "\\\"")
|
||||
.Replace("&", "\\&");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats phone numbers to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonPhoneNumbers(Contact con)
|
||||
{
|
||||
string retVal = string.Empty;
|
||||
const string ContactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
|
||||
foreach (ContactPhoneNumber number in con.PhoneNumbers)
|
||||
{
|
||||
string contactField = string.Format(ContactFieldFormat, number.Kind.ToString(), number.PhoneNumber);
|
||||
retVal += "{" + contactField + "},";
|
||||
}
|
||||
|
||||
return retVal.TrimEnd(',');
|
||||
}
|
||||
|
||||
/*
|
||||
* formatted: The complete name of the contact. (DOMString)
|
||||
familyName: The contacts family name. (DOMString)
|
||||
givenName: The contacts given name. (DOMString)
|
||||
middleName: The contacts middle name. (DOMString)
|
||||
honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
|
||||
honorificSuffix: The contacts suffix (example Esq.). (DOMString)
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Formats the name to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonName(Contact con)
|
||||
{
|
||||
string retVal;
|
||||
const string FormatStr = "\"formatted\":\"{0}\"," +
|
||||
"\"familyName\":\"{1}\"," +
|
||||
"\"givenName\":\"{2}\"," +
|
||||
"\"middleName\":\"{3}\"," +
|
||||
"\"honorificPrefix\":\"{4}\"," +
|
||||
"\"honorificSuffix\":\"{5}\"";
|
||||
|
||||
if (con.CompleteName != null)
|
||||
{
|
||||
retVal = string.Format(
|
||||
FormatStr,
|
||||
EscapeJson(con.CompleteName.FirstName + " " + con.CompleteName.LastName),
|
||||
//// TODO: does this need suffix? middlename?
|
||||
EscapeJson(con.CompleteName.LastName),
|
||||
EscapeJson(con.CompleteName.FirstName),
|
||||
EscapeJson(con.CompleteName.MiddleName),
|
||||
EscapeJson(con.CompleteName.Title),
|
||||
EscapeJson(con.CompleteName.Suffix));
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = string.Format(FormatStr, "", "", "", "", "", "");
|
||||
}
|
||||
|
||||
return "{" + retVal + "}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format Emails to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonEmails(Contact con)
|
||||
{
|
||||
string retVal = string.Empty;
|
||||
const string ContactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
|
||||
foreach (ContactEmailAddress address in con.EmailAddresses)
|
||||
{
|
||||
string contactField = string.Format(
|
||||
ContactFieldFormat,
|
||||
address.Kind.ToString(),
|
||||
EscapeJson(address.EmailAddress));
|
||||
|
||||
retVal += "{" + contactField + "},";
|
||||
}
|
||||
|
||||
return retVal.TrimEnd(',');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format Addresses to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonAddresses(Contact con)
|
||||
{
|
||||
string retVal = string.Empty;
|
||||
foreach (ContactAddress address in con.Addresses)
|
||||
{
|
||||
retVal += GetFormattedJsonAddress(address, false) + ",";
|
||||
}
|
||||
|
||||
return retVal.TrimEnd(',');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format Websites to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonWebsites(Contact con)
|
||||
{
|
||||
string retVal = string.Empty;
|
||||
foreach (string website in con.Websites)
|
||||
{
|
||||
retVal += "\"" + EscapeJson(website) + "\",";
|
||||
}
|
||||
|
||||
return retVal.TrimEnd(',');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format single address to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// Contact address.
|
||||
/// </param>
|
||||
/// <param name="isPrefered">
|
||||
/// Contact is preferred?
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// JSON string
|
||||
/// </returns>
|
||||
private static string GetFormattedJsonAddress(ContactAddress address, bool isPrefered)
|
||||
{
|
||||
const string AddressFormatString = "\"pref\":{0}," + // bool
|
||||
"\"type\":\"{1}\"," +
|
||||
"\"formatted\":\"{2}\"," +
|
||||
"\"streetAddress\":\"{3}\"," +
|
||||
"\"locality\":\"{4}\"," +
|
||||
"\"region\":\"{5}\"," +
|
||||
"\"postalCode\":\"{6}\"," +
|
||||
"\"country\":\"{7}\"";
|
||||
|
||||
string formattedAddress = EscapeJson(address.PhysicalAddress.AddressLine1 + " "
|
||||
+ address.PhysicalAddress.AddressLine2 + " "
|
||||
+ address.PhysicalAddress.City + " "
|
||||
+ address.PhysicalAddress.StateProvince + " "
|
||||
+ address.PhysicalAddress.CountryRegion + " "
|
||||
+ address.PhysicalAddress.PostalCode);
|
||||
|
||||
string jsonAddress = string.Format(
|
||||
AddressFormatString,
|
||||
isPrefered ? "\"true\"" : "\"false\"",
|
||||
address.Kind.ToString(),
|
||||
formattedAddress,
|
||||
EscapeJson(address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2),
|
||||
address.PhysicalAddress.City,
|
||||
address.PhysicalAddress.StateProvince,
|
||||
address.PhysicalAddress.PostalCode,
|
||||
address.PhysicalAddress.CountryRegion);
|
||||
|
||||
return "{" + jsonAddress + "}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats contact photos to JSON string.
|
||||
/// </summary>
|
||||
/// <param name="con">Contact object</param>
|
||||
/// <returns>JSON string</returns>
|
||||
private static string FormatJsonPhotos(Contact con) {
|
||||
|
||||
// we return single photo since contact object instance contains single picture only
|
||||
var photoStream = con.GetPicture();
|
||||
|
||||
if (photoStream == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return String.Format("{{value:\"{0}\", type: \"data\", pref: false}}", GetImageContent(photoStream));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns image content in a form of base64 string
|
||||
/// </summary>
|
||||
/// <param name="stream">Image stream</param>
|
||||
/// <returns>Base64 representation of the image</returns>
|
||||
private static string GetImageContent(Stream stream)
|
||||
{
|
||||
byte[] imageContent = null;
|
||||
|
||||
try
|
||||
{
|
||||
int streamLength = (int)stream.Length;
|
||||
imageContent = new byte[streamLength + 1];
|
||||
stream.Read(imageContent, 0, streamLength);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(imageContent);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user