mirror of https://github.com/sipwise/jitsi.git
Adds edition for macosx address book contact properties. Avoids concurrent access to contact details. Corrects msoutlook subcategories for email and nickname.
parent
fd097c2eb2
commit
a6288b5c35
Binary file not shown.
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.addrbook.macosx;
|
||||
|
||||
import java.util.*;
|
||||
//import java.util.regex.*;
|
||||
|
||||
//import net.java.sip.communicator.plugin.addrbook.*;
|
||||
import net.java.sip.communicator.service.contactsource.*;
|
||||
//import net.java.sip.communicator.service.contactsource.ContactDetail.*;
|
||||
//import net.java.sip.communicator.service.protocol.*;
|
||||
//import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* The editable detail, change get changed and in addressbook.
|
||||
*
|
||||
* @author Lyubomir Marinov
|
||||
*/
|
||||
public class MacOSXAddrBookContactDetail
|
||||
extends EditableContactDetail
|
||||
{
|
||||
/**
|
||||
* The property index for this detail.
|
||||
*/
|
||||
private final int property;
|
||||
|
||||
/**
|
||||
* The id of the detail.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
private String subPropertyLabel;
|
||||
|
||||
/**
|
||||
* Initializes a new <tt>ContactDetail</tt> instance which is to represent a
|
||||
* specific contact address and which is to be optionally labeled with a
|
||||
* specific set of labels.
|
||||
*
|
||||
* @param contactDetailValue the contact detail value to be represented by
|
||||
* the new <tt>ContactDetail</tt> instance
|
||||
* @param category
|
||||
* @param subCategories the set of sub categories with which the new
|
||||
* <tt>ContactDetail</tt> instance is to be labeled.
|
||||
* @param id The id of the detail.
|
||||
*/
|
||||
public MacOSXAddrBookContactDetail(
|
||||
int property,
|
||||
String contactDetailValue,
|
||||
Category category,
|
||||
SubCategory[] subCategories,
|
||||
String subPropertyLabel,
|
||||
String id)
|
||||
{
|
||||
super(contactDetailValue, category, subCategories);
|
||||
this.property = property;
|
||||
this.subPropertyLabel = subPropertyLabel;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the value for the category are multiline.
|
||||
* @param category
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMultiline(Category category)
|
||||
{
|
||||
switch(category)
|
||||
{
|
||||
case Personal:
|
||||
return false;
|
||||
case Organization:
|
||||
return false;
|
||||
case Email:
|
||||
return true;
|
||||
case InstantMessaging:
|
||||
return true;
|
||||
case Phone:
|
||||
return true;
|
||||
case Address:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given detail value.
|
||||
*
|
||||
* @param value the new value of the detail
|
||||
*/
|
||||
public void setDetail(String value)
|
||||
{
|
||||
//let's save in addressbook
|
||||
if(isMultiline(getCategory()))
|
||||
{
|
||||
// get others
|
||||
EditableSourceContact sourceContact = getSourceContact();
|
||||
if(sourceContact != null
|
||||
&& sourceContact instanceof MacOSXAddrBookSourceContact)
|
||||
{
|
||||
List<ContactDetail> details =
|
||||
((MacOSXAddrBookSourceContact) sourceContact)
|
||||
.getContactDetails(getCategory());
|
||||
|
||||
boolean isAddress =
|
||||
property == MacOSXAddrBookContactQuery.kABAddressProperty;
|
||||
boolean isHomeAddress = containsSubCategory(SubCategory.Home);
|
||||
// For an address, we must check that the current detail is the
|
||||
// modified one. For all other properties than address, this
|
||||
// boolean must always be true.
|
||||
boolean isModifiedAddressOrGenericDetail;
|
||||
|
||||
// first add existing one
|
||||
List<String> values = new ArrayList<String>();
|
||||
for(ContactDetail cd : details)
|
||||
{
|
||||
isModifiedAddressOrGenericDetail = true;
|
||||
if(isAddress)
|
||||
{
|
||||
// lets check home and work details
|
||||
if((isHomeAddress
|
||||
&& !cd.containsSubCategory(SubCategory.Home)
|
||||
)
|
||||
|| (!isHomeAddress
|
||||
&& !cd.containsSubCategory(SubCategory.Work)
|
||||
))
|
||||
{
|
||||
isModifiedAddressOrGenericDetail = false;
|
||||
}
|
||||
}
|
||||
|
||||
String det = cd.getDetail();
|
||||
|
||||
for(SubCategory sub : cd.getSubCategories())
|
||||
{
|
||||
String label
|
||||
= MacOSXAddrBookContactQuery.
|
||||
getLabel(property, sub, subPropertyLabel);
|
||||
|
||||
if(label != null)
|
||||
{
|
||||
if(getSubCategories().contains(sub)
|
||||
&& isModifiedAddressOrGenericDetail)
|
||||
values.add(value);
|
||||
else
|
||||
values.add(det);
|
||||
|
||||
values.add(label);
|
||||
|
||||
// For an address adds a third item for the tuple:
|
||||
// value, label, sub-property label.
|
||||
if(isAddress
|
||||
&& cd instanceof MacOSXAddrBookContactDetail
|
||||
)
|
||||
{
|
||||
values.add(
|
||||
((MacOSXAddrBookContactDetail) cd)
|
||||
.getSubPropertyLabel());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now the real edit
|
||||
MacOSXAddrBookContactQuery.setProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
property],
|
||||
subPropertyLabel,
|
||||
values.toArray(new Object[values.size()]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MacOSXAddrBookContactQuery.setProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
property],
|
||||
null,
|
||||
value);
|
||||
}
|
||||
|
||||
super.setDetail(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sub property.
|
||||
* @return
|
||||
*/
|
||||
public String getSubPropertyLabel()
|
||||
{
|
||||
return subPropertyLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property index for this detail.
|
||||
*
|
||||
* @return The property index for this detail.
|
||||
*/
|
||||
public final int getProperty()
|
||||
{
|
||||
return this.property;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.addrbook.macosx;
|
||||
|
||||
import java.util.*;
|
||||
//import java.util.regex.*;
|
||||
|
||||
//import net.java.sip.communicator.plugin.addrbook.*;
|
||||
import net.java.sip.communicator.service.contactsource.*;
|
||||
import net.java.sip.communicator.service.contactsource.ContactDetail.*;
|
||||
//import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* Our editable source contact, we store changes in the addressbook.
|
||||
*
|
||||
* @author Lyubomir Marinov
|
||||
*/
|
||||
public class MacOSXAddrBookSourceContact
|
||||
extends GenericSourceContact
|
||||
implements EditableSourceContact
|
||||
{
|
||||
/**
|
||||
* The <tt>Logger</tt> used by the <tt>MacOSXAddrBookSourceContact</tt>
|
||||
* class and its instances for logging output.
|
||||
*/
|
||||
private static final Logger logger
|
||||
= Logger.getLogger(MacOSXAddrBookSourceContact.class);
|
||||
|
||||
/**
|
||||
* Initializes a new <tt>AddrBookSourceContact</tt> instance.
|
||||
*
|
||||
* @param contactSource the <tt>ContactSourceService</tt> which is creating
|
||||
* the new instance
|
||||
* @param displayName the display name of the new instance
|
||||
* @param contactDetails the <tt>ContactDetail</tt>s of the new instance
|
||||
*/
|
||||
public MacOSXAddrBookSourceContact(
|
||||
ContactSourceService contactSource,
|
||||
String displayName,
|
||||
List<ContactDetail> contactDetails)
|
||||
{
|
||||
super(contactSource, displayName, contactDetails);
|
||||
|
||||
// let's save the parent so we can reuse it later when editing
|
||||
// the detail
|
||||
for(ContactDetail cd : contactDetails)
|
||||
{
|
||||
if(cd instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
((MacOSXAddrBookContactDetail)cd).setSourceContact(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a contact detail to the list of contact details.
|
||||
*
|
||||
* @param detail the <tt>ContactDetail</tt> to add
|
||||
*/
|
||||
public void addContactDetail(ContactDetail detail)
|
||||
{
|
||||
synchronized(this.contactDetails)
|
||||
{
|
||||
String id = (String)getData(SourceContact.DATA_ID);
|
||||
|
||||
if(id == null)
|
||||
{
|
||||
logger.warn("No id or wrong ContactDetail " + detail);
|
||||
return;
|
||||
}
|
||||
|
||||
String subProperty = null;
|
||||
int property = MacOSXAddrBookContactQuery.getProperty(
|
||||
detail.getCategory(),
|
||||
detail.getSubCategories());
|
||||
|
||||
if(MacOSXAddrBookContactDetail.isMultiline(detail.getCategory()))
|
||||
{
|
||||
if(detail instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
subProperty = ((MacOSXAddrBookContactDetail)detail)
|
||||
.getSubPropertyLabel();
|
||||
}
|
||||
|
||||
if(subProperty == null
|
||||
&& property
|
||||
== MacOSXAddrBookContactQuery.kABAddressProperty)
|
||||
{
|
||||
if(detail.containsSubCategory(SubCategory.Home))
|
||||
subProperty
|
||||
= MacOSXAddrBookContactQuery.kABAddressHomeLabel();
|
||||
else
|
||||
subProperty
|
||||
= MacOSXAddrBookContactQuery.kABAddressWorkLabel();
|
||||
}
|
||||
|
||||
List<String> values
|
||||
= getValues(detail, property, subProperty, true);
|
||||
|
||||
MacOSXAddrBookContactQuery.setProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
property],
|
||||
subProperty,
|
||||
values.toArray(new Object[values.size()]));
|
||||
}
|
||||
else
|
||||
{
|
||||
MacOSXAddrBookContactQuery.setProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
property],
|
||||
null,
|
||||
detail.getDetail());
|
||||
}
|
||||
|
||||
// make sure we add AddressBookContactDetail
|
||||
Collection<SubCategory> subCategories
|
||||
= detail.getSubCategories();
|
||||
|
||||
MacOSXAddrBookContactDetail contactDetail
|
||||
= new MacOSXAddrBookContactDetail(
|
||||
property,
|
||||
detail.getDetail(),
|
||||
detail.getCategory(),
|
||||
subCategories.toArray(
|
||||
new SubCategory[
|
||||
subCategories.size()]),
|
||||
subProperty,
|
||||
id);
|
||||
contactDetail.setSourceContact(this);
|
||||
|
||||
// Add the detail at the right index : group multiline properties
|
||||
// together , such as home/work address fields.
|
||||
boolean added = false;
|
||||
int index = 0;
|
||||
for(ContactDetail cd: contactDetails)
|
||||
{
|
||||
if(cd instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
MacOSXAddrBookContactDetail macOSXcd
|
||||
= (MacOSXAddrBookContactDetail) cd;
|
||||
if(!added
|
||||
&& contactDetail.getProperty()
|
||||
== macOSXcd.getProperty()
|
||||
&& (contactDetail.getSubPropertyLabel() == null
|
||||
|| contactDetail.getSubPropertyLabel().equals(
|
||||
macOSXcd.getSubPropertyLabel())))
|
||||
{
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
if(!added)
|
||||
++index;
|
||||
}
|
||||
|
||||
contactDetails.add(index, contactDetail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of values that will be saved.
|
||||
* @param detail the current modified detail
|
||||
* @param property the property we change
|
||||
* @param subProperty the subproperty that is changed
|
||||
* @param addDetail should we add <tt>detail</tt> to the list of values.
|
||||
* @return the list of values to be saved.
|
||||
*/
|
||||
private List<String> getValues(ContactDetail detail,
|
||||
int property,
|
||||
String subProperty,
|
||||
boolean addDetail)
|
||||
{
|
||||
// first add existing one
|
||||
List<String> values = new ArrayList<String>();
|
||||
|
||||
List<ContactDetail> details =
|
||||
getContactDetails(detail.getCategory());
|
||||
|
||||
boolean isIM =
|
||||
(property == MacOSXAddrBookContactQuery.kABICQInstantProperty
|
||||
|| property == MacOSXAddrBookContactQuery.kABAIMInstantProperty
|
||||
|| property == MacOSXAddrBookContactQuery.kABYahooInstantProperty
|
||||
|| property == MacOSXAddrBookContactQuery.kABMSNInstantProperty
|
||||
|| property == MacOSXAddrBookContactQuery.kABJabberInstantProperty
|
||||
);
|
||||
|
||||
boolean isAddress
|
||||
= property == MacOSXAddrBookContactQuery.kABAddressProperty;
|
||||
boolean isHomeAddress =
|
||||
detail.containsSubCategory(SubCategory.Home);
|
||||
int lastHomeIndex = 0;
|
||||
int lastWorkIndex = 0;
|
||||
|
||||
for(ContactDetail cd : details)
|
||||
{
|
||||
// if the detail exists do not added, in case of add there is
|
||||
// sense the detail to be added twice. In case of remove
|
||||
// we miss the detail
|
||||
if(cd.equals(detail))
|
||||
continue;
|
||||
|
||||
String det = cd.getDetail();
|
||||
|
||||
for(SubCategory sub : cd.getSubCategories())
|
||||
{
|
||||
// if its an im property check also if the detail
|
||||
// is the same subcategory (which is icq, yahoo, ...)
|
||||
if(isIM && !detail.getSubCategories().contains(sub))
|
||||
continue;
|
||||
|
||||
String label =
|
||||
MacOSXAddrBookContactQuery.
|
||||
getLabel(property, sub, subProperty);
|
||||
if(label != null)
|
||||
{
|
||||
values.add(det);
|
||||
values.add(label);
|
||||
|
||||
// For an address adds a third item for the tuple:
|
||||
// value, label, sub-property label.
|
||||
if(isAddress
|
||||
&& cd instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
String subPropertyLabel
|
||||
= ((MacOSXAddrBookContactDetail) cd)
|
||||
.getSubPropertyLabel();
|
||||
values.add(subPropertyLabel);
|
||||
|
||||
if(subPropertyLabel.equals(
|
||||
MacOSXAddrBookContactQuery
|
||||
.kABAddressHomeLabel()))
|
||||
{
|
||||
lastHomeIndex = values.size();
|
||||
}
|
||||
else if(subPropertyLabel.equals(
|
||||
MacOSXAddrBookContactQuery
|
||||
.kABAddressWorkLabel()))
|
||||
{
|
||||
lastWorkIndex = values.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(addDetail)
|
||||
{
|
||||
// now the new value to add
|
||||
for(SubCategory sub : detail.getSubCategories())
|
||||
{
|
||||
String label =
|
||||
MacOSXAddrBookContactQuery.
|
||||
getLabel(property, sub, subProperty);
|
||||
if(label != null)
|
||||
{
|
||||
// For an address adds a third item for the tuple:
|
||||
// value, label, sub-property label.
|
||||
if(isAddress)
|
||||
{
|
||||
String subPropertyLabel = "";
|
||||
int index = values.size();
|
||||
if(isHomeAddress)
|
||||
{
|
||||
subPropertyLabel
|
||||
= MacOSXAddrBookContactQuery
|
||||
.kABAddressHomeLabel();
|
||||
index = lastHomeIndex;
|
||||
if(lastWorkIndex > lastHomeIndex)
|
||||
{
|
||||
lastWorkIndex += 3;
|
||||
}
|
||||
lastHomeIndex += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
subPropertyLabel
|
||||
= MacOSXAddrBookContactQuery
|
||||
.kABAddressWorkLabel();
|
||||
index = lastWorkIndex;
|
||||
if(lastHomeIndex > lastWorkIndex)
|
||||
{
|
||||
lastHomeIndex += 3;
|
||||
}
|
||||
lastWorkIndex += 3;
|
||||
}
|
||||
values.add(index, detail.getDetail());
|
||||
values.add(index + 1, label);
|
||||
values.add(index + 2, subPropertyLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
values.add(detail.getDetail());
|
||||
values.add(label);
|
||||
}
|
||||
}
|
||||
else
|
||||
logger.warn("Missing label fo prop:" + property
|
||||
+ " and sub:" + sub);
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given <tt>ContactDetail</tt> from the list of details for
|
||||
* this <tt>SourceContact</tt>.
|
||||
*
|
||||
* @param detail the <tt>ContactDetail</tt> to remove
|
||||
*/
|
||||
public void removeContactDetail(ContactDetail detail)
|
||||
{
|
||||
synchronized(this.contactDetails)
|
||||
{
|
||||
//remove the detail from the addressbook
|
||||
String id = (String)getData(SourceContact.DATA_ID);
|
||||
if(id != null && detail instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
if(MacOSXAddrBookContactDetail.isMultiline(
|
||||
detail.getCategory()))
|
||||
{
|
||||
String subProperty = null;
|
||||
|
||||
if(detail instanceof MacOSXAddrBookContactDetail)
|
||||
{
|
||||
subProperty = ((MacOSXAddrBookContactDetail)detail)
|
||||
.getSubPropertyLabel();
|
||||
}
|
||||
|
||||
List<String> values =
|
||||
getValues(
|
||||
detail,
|
||||
((MacOSXAddrBookContactDetail)detail)
|
||||
.getProperty(),
|
||||
subProperty,
|
||||
false);
|
||||
|
||||
MacOSXAddrBookContactQuery.setProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
((MacOSXAddrBookContactDetail) detail)
|
||||
.getProperty()],
|
||||
subProperty,
|
||||
values.toArray(new Object[values.size()]));
|
||||
}
|
||||
else
|
||||
MacOSXAddrBookContactQuery.removeProperty(
|
||||
id,
|
||||
MacOSXAddrBookContactQuery.ABPERSON_PROPERTIES[
|
||||
((MacOSXAddrBookContactDetail) detail)
|
||||
.getProperty()]);
|
||||
}
|
||||
else
|
||||
logger.warn("No id or wrong ContactDetail " + detail);
|
||||
|
||||
contactDetails.remove(detail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the details list with the supplied one.
|
||||
* @param details the details.
|
||||
*/
|
||||
public void setDetails(List<ContactDetail> details)
|
||||
{
|
||||
synchronized(this.contactDetails)
|
||||
{
|
||||
contactDetails.clear();
|
||||
contactDetails.addAll(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue