blob: 1a439d92a62c855b977aa7246065ada66fb11bac [file] [log] [blame]
/*
* Contacts.cpp
*
* Created on: Mar 25, 2011
* Author: Anis Kadri <anis@adobe.com>
*
* 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.
*/
#include "../inc/Contacts.h"
Contacts::Contacts(Web* pWeb) : CordovaCommand(pWeb) {
}
Contacts::~Contacts() {
}
void
Contacts::Run(const String& command) {
if(!command.IsEmpty()) {
Uri commandUri;
commandUri.SetUri(command);
String method = commandUri.GetHost();
StringTokenizer strTok(commandUri.GetPath(), L"/");
if(strTok.GetTokenCount() < 2) {
AppLogException("Not enough params");
return;
}
strTok.GetNextToken(callbackId);
// Saving a new contact
if(method == L"com.cordova.Contacts.save" && !callbackId.IsEmpty()) {
String contactId;
strTok.GetNextToken(contactId);
int cid = -1;
result r = E_SUCCESS;
r = Integer::Parse(contactId, cid);
if(IsFailed(r)) {
AppLogException("Could not retrieve contact ID");
}
AppLogDebug("Method %S callbackId %S contactId %d", method.GetPointer(), callbackId.GetPointer(), cid);
Create(cid);
// Finding an exisiting contact by Name/Phone Number/Email
} else if(method == L"com.cordova.Contacts.find" && !callbackId.IsEmpty()) {
String filter;
strTok.GetNextToken(filter);
AppLogDebug("Method %S callbackId %S filter %S", method.GetPointer(), callbackId.GetPointer(), filter.GetPointer());
Find(filter);
} else if(method == L"com.cordova.Contacts.remove" && !callbackId.IsEmpty()) {
String id;
strTok.GetNextToken(id);
AppLogDebug("Method %S callbackId %S ID to remove %S", method.GetPointer(), callbackId.GetPointer(), id.GetPointer());
Remove(id);
}
}
}
void
Contacts::SetNickname(Contact& contact, const int cid) {
String* value = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].nickname", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("nickname: %S", value->GetPointer());
contact.SetValue(CONTACT_PROPERTY_ID_NICK_NAME, *value);
}
delete value;
}
void
Contacts::SetFirstName(Contact& contact, const int cid) {
String* value = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].name.givenName", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("First Name: %S", value->GetPointer());
contact.SetValue(CONTACT_PROPERTY_ID_FIRST_NAME, *value);
}
delete value;
}
void
Contacts::SetLastName(Contact& contact, const int cid) {
String* value = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].name.familyName", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("Last Name: %S", value->GetPointer());
contact.SetValue(CONTACT_PROPERTY_ID_LAST_NAME, *value);
}
delete value;
}
void
Contacts::SetPhoneNumbers(Contact& contact, const int cid) {
// Getting phone numbers length
String* lengthStr = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers.length", cid);
lengthStr = pWeb->EvaluateJavascriptN(eval);
if(!lengthStr->IsEmpty()) {
int length;
result r = Integer::Parse(*lengthStr, length);
if(IsFailed(r)) {
AppLogException("Could not get phoneNumbers length");
return;
}
delete lengthStr;
for(int i = 0 ; i < length ; i++) {
String* type = NULL;
String* number = NULL;
// Getting phone number type
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers[%d].type", cid, i);
type = pWeb->EvaluateJavascriptN(eval);
// Getting phone number
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers[%d].value", cid, i);
number = pWeb->EvaluateJavascriptN(eval);
if(!type->IsEmpty() && !number->IsEmpty()) {
if(*type == "Home") {
AppLogDebug("Adding HOME phone number %S", number->GetPointer());
PhoneNumber phoneNumber(PHONENUMBER_TYPE_HOME, *number);
contact.AddPhoneNumber(phoneNumber);
} else if(*type == "Mobile") {
AppLogDebug("Adding MOBILE phone number %S", number->GetPointer());
PhoneNumber phoneNumber(PHONENUMBER_TYPE_MOBILE, *number);
contact.AddPhoneNumber(phoneNumber);
} else if(*type == "Pager") {
AppLogDebug("Adding PAGER phone number %S", number->GetPointer());
PhoneNumber phoneNumber(PHONENUMBER_TYPE_PAGER, *number);
contact.AddPhoneNumber(phoneNumber);
} else if(*type == "Work") {
AppLogDebug("Adding WORK phone number %S", number->GetPointer());
PhoneNumber phoneNumber(PHONENUMBER_TYPE_WORK, *number);
contact.AddPhoneNumber(phoneNumber);
} else if(*type == "Other") {
AppLogDebug("Adding OTHER phone number %S", number->GetPointer());
PhoneNumber phoneNumber(PHONENUMBER_TYPE_OTHER, *number);
contact.AddPhoneNumber(phoneNumber);
}
}
delete type;
delete number;
}
}
}
void
Contacts::SetEmails(Contact& contact, const int cid) {
// Getting emails length
String* lengthStr = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].emails.length", cid);
lengthStr = pWeb->EvaluateJavascriptN(eval);
if(!lengthStr->IsEmpty()) {
int length;
result r = Integer::Parse(*lengthStr, length);
if(IsFailed(r)) {
AppLogException("Could not get emails length");
return;
}
delete lengthStr;
for(int i = 0 ; i < length ; i++) {
String* type = NULL;
String* address = NULL;
// Getting email type
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].emails[%d].type", cid, i);
type = pWeb->EvaluateJavascriptN(eval);
// Getting email
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].emails[%d].value", cid, i);
address = pWeb->EvaluateJavascriptN(eval);
if(!type->IsEmpty() && !address->IsEmpty()) {
if(*type == "Personal") {
AppLogDebug("Adding PERSONAL email %S", address->GetPointer());
Email email(EMAIL_TYPE_PERSONAL, *address);
contact.AddEmail(email);
} else if(*type == "Work") {
AppLogDebug("Adding WORK email %S", address->GetPointer());
Email email(EMAIL_TYPE_WORK, *address);
contact.AddEmail(email);
} else if(*type == "Other") {
AppLogDebug("Adding OTHER email %S", address->GetPointer());
Email email(EMAIL_TYPE_OTHER, *address);
contact.AddEmail(email);
}
}
delete type;
delete address;
}
}
}
void
Contacts::SetUrls(Contact& contact, const int cid) {
// Getting emails length
String* lengthStr = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].urls.length", cid);
lengthStr = pWeb->EvaluateJavascriptN(eval);
if(!lengthStr->IsEmpty()) {
int length;
result r = Integer::Parse(*lengthStr, length);
if(IsFailed(r)) {
AppLogException("Could not get urls length");
return;
}
delete lengthStr;
for(int i = 0 ; i < length ; i++) {
String* type = NULL;
String* address = NULL;
// Getting url type
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].urls[%d].type", cid, i);
type = pWeb->EvaluateJavascriptN(eval);
// Getting url
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].urls[%d].value", cid, i);
address = pWeb->EvaluateJavascriptN(eval);
if(!type->IsEmpty() && !address->IsEmpty()) {
if(*type == "Personal") {
AppLogDebug("Adding PERSONAL URL %S", address->GetPointer());
Url url(URL_TYPE_PERSONAL, *address);
contact.AddUrl(url);
} else if(*type == "Work") {
AppLogDebug("Adding WORK URL %S", address->GetPointer());
Url url(URL_TYPE_WORK, *address);
contact.AddUrl(url);
} else if(*type == "Other") {
AppLogDebug("Adding OTHER URL %S", address->GetPointer());
Url url(URL_TYPE_OTHER, *address);
contact.AddUrl(url);
}
}
delete type;
delete address;
}
}
}
void
Contacts::SetOrganization(Contact& contact, const int cid) {
// Setting Organization Name
String* value = NULL;
String eval;
eval.Format(128, L"navigator.service.contacts.records[%d].organization.name", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("Organization Name: %S", value->GetPointer());
contact.SetValue(CONTACT_PROPERTY_ID_COMPANY, *value);
}
delete value;
// Setting Organization Title
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].organization.title", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("Organization Title: %S", value->GetPointer());
contact.SetValue(CONTACT_PROPERTY_ID_JOB_TITLE, *value);
}
delete value;
}
void
Contacts::SetBirthday(Contact& contact, const int cid) {
String* value;
String eval;
int year, month, day;
DateTime birthday;
// Setting Year
eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getFullYear()", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
result r = Integer::Parse(*value, year);
if(IsFailed(r)) {
AppLogException("Could not get birthday Year");
return;
}
AppLogDebug("Birthday Year: %S", value->GetPointer());
}
delete value;
// Setting Month
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getMonth() + 1", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
result r = Integer::Parse(*value, month);
if(IsFailed(r)) {
AppLogException("Could not get birthday Month");
return;
}
AppLogDebug("Birthday Month: %S", value->GetPointer());
}
delete value;
// Setting Day
eval.Clear();
eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getDate()", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
result r = Integer::Parse(*value, day);
if(IsFailed(r)) {
AppLogException("Could not get birthday Day");
return;
}
AppLogDebug("Birthday Day: %S", value->GetPointer());
}
delete value;
birthday.SetValue(year, month, day);
contact.SetValue(CONTACT_PROPERTY_ID_BIRTHDAY, birthday);
AppLogDebug("Birthday %d/%d/%d added", year, month, day);
}
void
Contacts::SetAddress(Contact& contact, const int cid) {
Address address;
String* value;
String eval;
// Setting Street Address
eval.Format(128, L"navigator.service.contacts.records[%d].address.streetAddress", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("Street Address: %S", value->GetPointer());
address.SetStreet(*value);
}
delete value;
// Setting City
eval.Format(128, L"navigator.service.contacts.records[%d].address.locality", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("City: %S", value->GetPointer());
address.SetCity(*value);
}
delete value;
// Setting State
eval.Format(128, L"navigator.service.contacts.records[%d].address.region", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("State: %S", value->GetPointer());
address.SetState(*value);
}
delete value;
// Setting Postal Code
eval.Format(128, L"navigator.service.contacts.records[%d].address.postalCode", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("Postal Code: %S", value->GetPointer());
address.SetPostalCode(*value);
}
delete value;
// Setting Country
eval.Format(128, L"navigator.service.contacts.records[%d].address.country", cid);
value = pWeb->EvaluateJavascriptN(eval);
if(!value->IsEmpty()) {
AppLogDebug("County: %S", value->GetPointer());
address.SetPostalCode(*value);
}
delete value;
contact.AddAddress(address);
AppLogDebug("Address Added");
}
void
Contacts::Create(const int cid) {
result r = E_SUCCESS;
Addressbook addressbook;
r = addressbook.Construct();
if(IsFailed(r)) {
AppLogException("Could not create AddressBook");
return;
}
Contact contact;
SetNickname(contact, cid);
SetFirstName(contact, cid);
SetLastName(contact, cid);
SetPhoneNumbers(contact, cid);
SetEmails(contact, cid);
SetUrls(contact, cid);
SetOrganization(contact, cid);
SetBirthday(contact, cid);
SetAddress(contact, cid);
r = addressbook.AddContact(contact);
String eval;
if(IsFailed(r)) {
AppLogException("Could not add contact");
eval.Format(128, L"Cordova.callbacks['%S'].fail({message:'%s',code:%d})", callbackId.GetPointer(), r, GetErrorMessage(r));
pWeb->EvaluateJavascriptN(eval);
} else {
AppLogDebug("Contact Successfully Added");
eval.Format(128, L"Cordova.callbacks['%S'].success({message:'Contact added successfully'})", callbackId.GetPointer());
AppLogDebug("%S", eval.GetPointer());
pWeb->EvaluateJavascriptN(eval);
}
}
void
Contacts::UpdateSearch(Contact* pContact) const {
// TODO: update this add other fields too (emails, urls, phonenumbers, etc...)
String eval, displayName, firstName, lastName;
RecordId recordId = pContact->GetRecordId();
LongLong test(recordId);
pContact->GetValue(CONTACT_PROPERTY_ID_DISPLAY_NAME, displayName);
pContact->GetValue(CONTACT_PROPERTY_ID_FIRST_NAME, firstName);
pContact->GetValue(CONTACT_PROPERTY_ID_LAST_NAME, lastName);
eval.Format(256, L"navigator.service.contacts._findCallback({id:'%S', displayName:'%S', name:{firstName:'%S',lastName:'%S'}})",
test.ToString().GetPointer(),
displayName.GetPointer(),
firstName.GetPointer(),
lastName.GetPointer());
//AppLogDebug("%S", eval.GetPointer());
pWeb->EvaluateJavascriptN(eval);
}
void
Contacts::FindByName(const String& filter) {
Addressbook addressbook;
Contact* pContact = null;
IList* pContactList = null;
IEnumerator* pContactEnum = null;
String displayName, firstName, lastName;
result r = addressbook.Construct();
if(IsFailed(r))
{
return;
}
// Searching by Email
pContactList = addressbook.SearchContactsByNameN(filter);
AppLogDebug("Names Matched %d", pContactList->GetCount());
pContactEnum = pContactList->GetEnumeratorN();
while (E_SUCCESS == pContactEnum->MoveNext())
{
pContact = (Contact*) pContactEnum->GetCurrent();
UpdateSearch(pContact);
}
delete pContactEnum;
pContactList->RemoveAll(true);
delete pContactList;
}
void
Contacts::FindByEmail(const String& filter) {
Addressbook addressbook;
Contact* pContact = null;
IList* pContactList = null;
IEnumerator* pContactEnum = null;
String displayName, firstName, lastName;
result r = addressbook.Construct();
if(IsFailed(r))
{
return;
}
// Searching by Email
pContactList = addressbook.SearchContactsByEmailN(filter);
AppLogDebug("Emails Matched %d", pContactList->GetCount());
pContactEnum = pContactList->GetEnumeratorN();
while (E_SUCCESS == pContactEnum->MoveNext())
{
pContact = (Contact*) pContactEnum->GetCurrent();
UpdateSearch(pContact);
}
delete pContactEnum;
pContactList->RemoveAll(true);
delete pContactList;
}
void
Contacts::FindByPhoneNumber(const String& filter) {
Addressbook addressbook;
Contact* pContact = null;
IList* pContactList = null;
IEnumerator* pContactEnum = null;
String displayName, firstName, lastName;
result r = addressbook.Construct();
if(IsFailed(r))
{
return;
}
// Searching by Email
pContactList = addressbook.SearchContactsByPhoneNumberN(filter);
AppLogDebug("Phone Number Matched %d", pContactList->GetCount());
pContactEnum = pContactList->GetEnumeratorN();
while (E_SUCCESS == pContactEnum->MoveNext())
{
pContact = (Contact*) pContactEnum->GetCurrent();
UpdateSearch(pContact);
}
delete pContactEnum;
pContactList->RemoveAll(true);
delete pContactList;
}
void
Contacts::Find(const String& filter) {
String eval;
String* value;
int length = 0;
// Resetting previous results
pWeb->EvaluateJavascriptN(L"navigator.service.contacts.results = new Array();");
// Searching by Name
FindByName(filter);
// Searching by PhoneNumber
FindByPhoneNumber(filter);
// Searching by Email
FindByEmail(filter);
value = pWeb->EvaluateJavascriptN(L"navigator.service.contacts.results.length");
AppLogDebug("Results length: %S", value->GetPointer());
result r = Integer::Parse(*value, length);
if(IsFailed(r)) {
AppLogException("Could not get Contact Results Length");
return;
}
delete value;
if(length > 0) {
eval.Format(128, L"Cordova.callbacks['%S'].success(navigator.service.contacts.results)", callbackId.GetPointer());
pWeb->EvaluateJavascriptN(eval);
} else {
eval.Format(128, L"Cordova.callbacks['%S'].fail({message:'no contacts found',code:00})", callbackId.GetPointer());
pWeb->EvaluateJavascriptN(eval);
}
}
void
Contacts::Remove(const String& idStr) {
String eval;
Addressbook addressbook;
RecordId id;
result r = addressbook.Construct();
if(IsFailed(r))
{
AppLogException("Could not construct Address Book");
return;
}
r = LongLong::Parse(idStr, id);
if(IsFailed(r)) {
AppLogException("Could not parse ID");
} else {
AppLogDebug("Trying to remove contact with ID %S", idStr.GetPointer());
r = addressbook.RemoveContact(id);
if(IsFailed(r)) {
AppLogDebug("Contact Could not be removed %s %d", GetErrorMessage(r), r);
eval.Format(256, L"Cordova.callbacks['%S'].fail({message:'%s', code:ContactError.NOT_FOUND_ERROR})",
callbackId.GetPointer(), GetErrorMessage(r));
pWeb->EvaluateJavascriptN(eval);
} else {
AppLogDebug("Contact %S removed", idStr.GetPointer());
eval.Format(256, L"Cordova.callbacks['%S'].success({message:'Contact with ID %d removed', code:01})", callbackId.GetPointer(), id);
pWeb->EvaluateJavascriptN(eval);
}
}
}