diff options
author | Damian Minkov <damencho@jitsi.org> | 2014-04-10 11:07:36 +0300 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2014-04-10 11:07:36 +0300 |
commit | db8071c2d4aba6bee1a02364aea5240ec1b07cbb (patch) | |
tree | 9c64349f317ca3c1c660c3270fa4ee70884cf511 /src/net | |
parent | a278bda96e28d3ff85ae9f269928c1214173fa5d (diff) | |
download | jitsi-db8071c2d4aba6bee1a02364aea5240ec1b07cbb.zip jitsi-db8071c2d4aba6bee1a02364aea5240ec1b07cbb.tar.gz jitsi-db8071c2d4aba6bee1a02364aea5240ec1b07cbb.tar.bz2 |
Separates phone number service, to be a service in separate bundle and improves the number matching when searching for phone numbers.
Diffstat (limited to 'src/net')
23 files changed, 584 insertions, 218 deletions
diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java index e061cba..7c33c7d 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsActivator.java @@ -71,6 +71,11 @@ public class GoogleContactsActivator implements BundleActivator = new HashMap<GoogleContactsSourceService, ServiceRegistration>(); /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + /** * Returns a reference to a ConfigurationService implementation currently * registered in the bundle context or null if no such implementation was * found. @@ -480,4 +485,20 @@ public class GoogleContactsActivator implements BundleActivator cssList.remove(found); } } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java index b653b95..f37121e 100644 --- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsQuery.java @@ -208,7 +208,8 @@ public class GoogleContactsQuery supportedOpSets.add(OperationSetBasicTelephony.class); // can be added as contacts supportedOpSets.add(OperationSetPersistentPresence.class); - homePhone = PhoneNumberI18nService.normalize(homePhone); + homePhone = GoogleContactsActivator.getPhoneNumberI18nService() + .normalize(homePhone); detail = new ContactDetail(homePhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ @@ -225,7 +226,8 @@ public class GoogleContactsQuery supportedOpSets.add(OperationSetBasicTelephony.class); // can be added as contacts supportedOpSets.add(OperationSetPersistentPresence.class); - workPhone = PhoneNumberI18nService.normalize(workPhone); + workPhone = GoogleContactsActivator.getPhoneNumberI18nService() + .normalize(workPhone); detail = new ContactDetail(workPhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ @@ -242,7 +244,8 @@ public class GoogleContactsQuery supportedOpSets.add(OperationSetBasicTelephony.class); // can be added as contacts supportedOpSets.add(OperationSetPersistentPresence.class); - mobilePhone = PhoneNumberI18nService.normalize(mobilePhone); + mobilePhone = GoogleContactsActivator.getPhoneNumberI18nService() + .normalize(mobilePhone); detail = new ContactDetail(mobilePhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java index 2fcdea8..cf7a9e0 100644 --- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java +++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java @@ -122,6 +122,11 @@ public class GuiActivator implements BundleActivator replacementSourcesMap = new Hashtable<String, ReplacementService>(); /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + /** * Indicates if this bundle has been started. */ public static boolean isStarted = false; @@ -910,4 +915,20 @@ public class GuiActivator implements BundleActivator MessageHistoryService.class); return messageHistoryService; } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java index 8622bb7..f27a7ae 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java @@ -912,7 +912,8 @@ public class CallManager if (ConfigurationUtils.isNormalizePhoneNumber() && !NetworkUtils.isValidIPAddress(callString)) { - callString = PhoneNumberI18nService.normalize(callString); + callString = GuiActivator.getPhoneNumberI18nService() + .normalize(callString); } List<ProtocolProviderService> telephonyProviders @@ -2519,8 +2520,8 @@ public class CallManager if (stringContact != null) { - stringContact - = PhoneNumberI18nService.normalize(stringContact); + stringContact = GuiActivator.getPhoneNumberI18nService() + .normalize(stringContact); } } @@ -3555,7 +3556,8 @@ public class CallManager private static void normalizePhoneNumbers(String callees[]) { for (int i = 0 ; i < callees.length ; i++) - callees[i] = PhoneNumberI18nService.normalize(callees[i]); + callees[i] = GuiActivator.getPhoneNumberI18nService() + .normalize(callees[i]); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java index 2413a78..1f993b1 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java @@ -59,6 +59,12 @@ public class SearchFilter = new HashMap<Integer, Integer>(); /** + * If set, we are searching a phone number and will use the phone number + * service to try matching the numbers. + */ + private boolean isSearchingPhoneNumber = false; + + /** * Creates an instance of <tt>SearchFilter</tt>. */ public SearchFilter(MetaContactListSource contactListSource) @@ -260,6 +266,9 @@ public class SearchFilter Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); + + this.isSearchingPhoneNumber + = GuiActivator.getPhoneNumberI18nService().isPhoneNumber(filter); } /** @@ -270,9 +279,10 @@ public class SearchFilter */ private boolean isMatching(String text) { - if (filterPattern != null) - return filterPattern.matcher(text).find(); - - return true; + return (filterPattern != null + && filterPattern.matcher(text).find()) + || (isSearchingPhoneNumber + && GuiActivator.getPhoneNumberI18nService() + .phoneNumbersMatch(this.filterString, text)); } } diff --git a/src/net/java/sip/communicator/impl/ldap/LdapActivator.java b/src/net/java/sip/communicator/impl/ldap/LdapActivator.java index 9e8a36f..2c3be39 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapActivator.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapActivator.java @@ -10,6 +10,7 @@ import java.util.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.ldap.*; +import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import org.jitsi.service.resources.*; @@ -61,6 +62,11 @@ public class LdapActivator new HashMap<LdapContactSourceService, ServiceRegistration>(); /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + /** * Starts the LDAP service * * @param bundleContext BundleContext @@ -231,4 +237,20 @@ public class LdapActivator cssList.remove(found); } } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/impl/ldap/LdapContactQuery.java b/src/net/java/sip/communicator/impl/ldap/LdapContactQuery.java index 99f98e4..e906204 100644 --- a/src/net/java/sip/communicator/impl/ldap/LdapContactQuery.java +++ b/src/net/java/sip/communicator/impl/ldap/LdapContactQuery.java @@ -149,7 +149,9 @@ public class LdapContactQuery Set<String> mobilePhones = person.getMobilePhone(); Set<String> homePhones = person.getHomePhone(); Set<String> workPhones = person.getWorkPhone(); - ContactDetail detail = null; + ContactDetail detail; + PhoneNumberI18nService phoneNumberI18nService + = LdapActivator.getPhoneNumberI18nService(); for(String mail : mailAddresses) { @@ -161,7 +163,7 @@ public class LdapContactQuery for(String homePhone : homePhones) { - homePhone = PhoneNumberI18nService.normalize(homePhone); + homePhone = phoneNumberI18nService.normalize(homePhone); detail = new ContactDetail(homePhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ @@ -175,7 +177,7 @@ public class LdapContactQuery for(String workPhone : workPhones) { - workPhone = PhoneNumberI18nService.normalize(workPhone); + workPhone = phoneNumberI18nService.normalize(workPhone); detail = new ContactDetail(workPhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ @@ -189,7 +191,7 @@ public class LdapContactQuery for(String mobilePhone : mobilePhones) { - mobilePhone = PhoneNumberI18nService.normalize(mobilePhone); + mobilePhone = phoneNumberI18nService.normalize(mobilePhone); detail = new ContactDetail(mobilePhone, ContactDetail.Category.Phone, new ContactDetail.SubCategory[]{ diff --git a/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java new file mode 100644 index 0000000..97f74df --- /dev/null +++ b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberI18nServiceImpl.java @@ -0,0 +1,241 @@ +/* + * 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.impl.phonenumbers; + +import com.google.i18n.phonenumbers.*; +import net.java.sip.communicator.service.protocol.*; +import org.jitsi.service.configuration.*; + +import java.util.regex.*; + +/** + * Implements <tt>PhoneNumberI18nService</tt> which aids the parsing, formatting + * and validating of international phone numbers. + * + * @author Lyubomir Marinov + * @author Vincent Lucas + * @author Damian Minkov + */ +public class PhoneNumberI18nServiceImpl + implements PhoneNumberI18nService +{ + /** + * The configuration service. + */ + private static ConfigurationService configService + = ProtocolProviderActivator.getConfigurationService(); + + /** + * Characters which have to be removed from a phone number in order to + * normalized it. + */ + private static final Pattern removedCharactersToNormalizedPhoneNumber + = Pattern.compile("[-\\(\\)\\.\\\\\\/ ]"); + + /** + * Characters which have to be removed from a number (which is not a phone + * number, such as a sip id, a jabber id, etc.) in order to normalized it. + */ + private static final Pattern removedCharactersToNormalizedIdentifier + = Pattern.compile("[\\(\\) ]"); + + /** + * The list of characters corresponding to the number 2 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber2 + = Pattern.compile("[abc]", Pattern.CASE_INSENSITIVE); + /** + * The list of characters corresponding to the number 3 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber3 + = Pattern.compile("[def]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 4 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber4 + = Pattern.compile("[ghi]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 5 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber5 + = Pattern.compile("[jkl]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 6 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber6 + = Pattern.compile("[mno]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 7 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber7 + = Pattern.compile("[pqrs]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 8 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber8 + = Pattern.compile("[tuv]", Pattern.CASE_INSENSITIVE); + + /** + * The list of characters corresponding to the number 9 in a phone dial pad. + */ + private static final Pattern charactersFordialPadNumber9 + = Pattern.compile("[wxyz]", Pattern.CASE_INSENSITIVE); + + /** + * Normalizes a <tt>String</tt> which may be a phone number or a identifier + * by removing useless characters and, if necessary, replacing the alpahe + * characters in corresponding dial pad numbers. + * + * @param possibleNumber a <tt>String</tt> which may represents a phone + * number or an identifier to normalize. + * + * @return a <tt>String</tt> which is a normalized form of the specified + * <tt>possibleNumber</tt>. + */ + public String normalize(String possibleNumber) + { + String normalizedNumber; + if(isPhoneNumber(possibleNumber)) + { + normalizedNumber = normalizePhoneNumber(possibleNumber); + } + else + { + normalizedNumber = normalizeIdentifier(possibleNumber); + } + + return normalizedNumber; + } + + + /** + * Normalizes a <tt>String</tt> phone number by converting alpha characters + * to their respective digits on a keypad and then stripping non-digit + * characters. + * + * @param phoneNumber a <tt>String</tt> which represents a phone number to + * normalize + * + * @return a <tt>String</tt> which is a normalized form of the specified + * <tt>phoneNumber</tt> + * + * @see net.java.sip.communicator.impl.phonenumbers.PhoneNumberI18nServiceImpl#normalize(String) + */ + private static String normalizePhoneNumber(String phoneNumber) + { + phoneNumber = convertAlphaCharactersInNumber(phoneNumber); + return removedCharactersToNormalizedPhoneNumber + .matcher(phoneNumber).replaceAll(""); + } + + /** + * Removes useless characters from a identifier (which is not a phone + * number) in order to normalized it. + * + * @param id The identifier string with some useless characters like: " ", + * "(", ")". + * + * @return The normalized identifier. + */ + private static String normalizeIdentifier(String id) + { + return removedCharactersToNormalizedIdentifier + .matcher(id).replaceAll(""); + } + + /** + * Determines whether two <tt>String</tt> phone numbers match. + * + * @param aPhoneNumber a <tt>String</tt> which represents a phone number to + * match to <tt>bPhoneNumber</tt> + * @param bPhoneNumber a <tt>String</tt> which represents a phone number to + * match to <tt>aPhoneNumber</tt> + * @return <tt>true</tt> if the specified <tt>String</tt>s match as phone + * numbers; otherwise, <tt>false</tt> + */ + public boolean phoneNumbersMatch(String aPhoneNumber, String bPhoneNumber) + { + PhoneNumberUtil.MatchType match = PhoneNumberUtil.getInstance() + .isNumberMatch(aPhoneNumber, bPhoneNumber); + + return match != PhoneNumberUtil.MatchType.NOT_A_NUMBER + && match != PhoneNumberUtil.MatchType.NO_MATCH; + } + + /** + * Indicates if the given string is possibly a phone number. + * + * @param possibleNumber the string to be verified + * @return <tt>true</tt> if the possibleNumber is a phone number, + * <tt>false</tt> - otherwise + */ + public boolean isPhoneNumber(String possibleNumber) + { + // If the string does not contains an "@", this may be a phone number. + if(possibleNumber.indexOf('@') == -1) + { + // If the string does not contain any alphabetical characters, then + // this is a phone number. + if(!possibleNumber.matches(".*[a-zA-Z].*")) + { + return true; + } + else + { + // Removes the " ", "(" and ")" in order to search the "+" + // character at the beginning at the string. + String tmpPossibleNumber + = possibleNumber.replaceAll(" \\(\\)", ""); + // If the property is enabled and the string starts with a "+", + // then we consider that this is a phone number. + if(configService.getBoolean( + "impl.gui.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS", + true) + && tmpPossibleNumber.startsWith("+")) + { + return true; + } + } + } + // Else the string is not a phone number. + return false; + } + + /** + * Changes all alphabetical characters into numbers, following phone dial + * pad disposition. + * + * @param phoneNumber The phone number string with some alphabetical + * characters. + * + * @return The phone number with all alphabetical caracters replaced with + * the corresponding dial pad number. + */ + private static String convertAlphaCharactersInNumber(String phoneNumber) + { + phoneNumber + = charactersFordialPadNumber2.matcher(phoneNumber).replaceAll("2"); + phoneNumber + = charactersFordialPadNumber3.matcher(phoneNumber).replaceAll("3"); + phoneNumber + = charactersFordialPadNumber4.matcher(phoneNumber).replaceAll("4"); + phoneNumber + = charactersFordialPadNumber5.matcher(phoneNumber).replaceAll("5"); + phoneNumber + = charactersFordialPadNumber6.matcher(phoneNumber).replaceAll("6"); + phoneNumber + = charactersFordialPadNumber7.matcher(phoneNumber).replaceAll("7"); + phoneNumber + = charactersFordialPadNumber8.matcher(phoneNumber).replaceAll("8"); + return charactersFordialPadNumber9.matcher(phoneNumber).replaceAll("9"); + } +} diff --git a/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberServiceActivator.java b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberServiceActivator.java new file mode 100644 index 0000000..3f36597 --- /dev/null +++ b/src/net/java/sip/communicator/impl/phonenumbers/PhoneNumberServiceActivator.java @@ -0,0 +1,44 @@ +/* + * 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.impl.phonenumbers; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; +import org.osgi.framework.*; + +/** + * Activates PhoneNumberI18nService implementation. + * + * @author Damian Minkov + */ +public class PhoneNumberServiceActivator + implements BundleActivator +{ + /** + * Our logging. + */ + private static Logger logger + = Logger.getLogger(PhoneNumberServiceActivator.class); + + @Override + public void start(BundleContext bundleContext) + throws Exception + { + bundleContext.registerService( + PhoneNumberI18nService.class.getName(), + new PhoneNumberI18nServiceImpl(), + null); + + if (logger.isInfoEnabled()) + logger.info("Packet Logging Service ...[REGISTERED]"); + } + + @Override + public void stop(BundleContext bundleContext) + throws Exception + {} +} diff --git a/src/net/java/sip/communicator/impl/phonenumbers/phonenumbers.manifest.mf b/src/net/java/sip/communicator/impl/phonenumbers/phonenumbers.manifest.mf new file mode 100644 index 0000000..8d33d43 --- /dev/null +++ b/src/net/java/sip/communicator/impl/phonenumbers/phonenumbers.manifest.mf @@ -0,0 +1,12 @@ +Bundle-Activator: net.java.sip.communicator.impl.phonenumbers.PhoneNumberServiceActivator +Bundle-Name: PhoneNumbers service +Bundle-Description: A bundle that provides arsing, formatting and validating of international phone numbers. +Bundle-Vendor: jitsi.org +Bundle-Version: 0.0.1 +Bundle-SymbolicName: net.java.sip.communicator.phonenumbers +Export-Package: com.google.i18n.phonenumbers +Import-Package: org.osgi.framework, + org.jitsi.service.configuration, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.util + diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java index 925f20e..b932d9c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/JabberActivator.java @@ -113,6 +113,11 @@ public class JabberActivator private static VersionService versionService = null; /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + /** * Called when this bundle is started so the Framework can perform the * bundle-specific activities necessary to start this bundle. * @@ -421,4 +426,20 @@ public class JabberActivator } return versionService; } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java index 28159be..9931c99 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java @@ -61,7 +61,8 @@ public class OperationSetCusaxUtilsJabberImpl while (phonesIter.hasNext()) { String phone = phonesIter.next(); - String normalizedPhone = PhoneNumberI18nService.normalize(phone); + String normalizedPhone = JabberActivator.getPhoneNumberI18nService() + .normalize(phone); if (phone.equals(detailAddress) || normalizedPhone.equals(detailAddress) diff --git a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java index 6867be9..28a9fe5 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java +++ b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java @@ -106,6 +106,11 @@ public class AddrBookActivator */ private static List<ProtocolProviderService> providers = new ArrayList<ProtocolProviderService>(); + + /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; /** * The registration change listener. @@ -524,4 +529,20 @@ public class AddrBookActivator return result; } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java index 2687f46..e73c9e8 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java +++ b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java @@ -589,7 +589,8 @@ public class MacOSXAddrBookContactQuery { if (kABPhoneProperty == property) stringValue - = PhoneNumberI18nService.normalize(stringValue); + = AddrBookActivator.getPhoneNumberI18nService() + .normalize(stringValue); contactDetails.add( setCapabilities( @@ -645,8 +646,9 @@ public class MacOSXAddrBookContactQuery { if (kABPhoneProperty == property) { - stringSubValue = PhoneNumberI18nService - .normalize(stringSubValue); + stringSubValue + = AddrBookActivator.getPhoneNumberI18nService() + .normalize(stringSubValue); } Object l = multiValue[multiValueIndex + 1]; diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java index b6c42ce..a7cdf73 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java +++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java @@ -999,7 +999,8 @@ public class MsOutlookAddrBookContactQuery { if(isPhoneNumber(property)) stringValue - = PhoneNumberI18nService.normalize(stringValue); + = AddrBookActivator.getPhoneNumberI18nService() + .normalize(stringValue); MsOutlookAddrBookContactDetail contactDetail = new MsOutlookAddrBookContactDetail( diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java index 4a3fc6f..e73ed02 100644 --- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java +++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java @@ -52,6 +52,11 @@ public class PNContactSourceActivator private static ResourceManagementService resources = null; /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + /** * Starts this bundle. * * @param context the bundle context where we register and obtain services. @@ -214,4 +219,20 @@ public class PNContactSourceActivator if (phoneProviders.contains(protocolProvider)) phoneProviders.remove(protocolProvider); } + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } } diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java index f58fbb7..42a8987 100644 --- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java +++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java @@ -45,6 +45,11 @@ public class PhoneNumberContactQuery new LinkedList<OperationSetPersistentPresence>()); /** + * Is the query searching for phone number. + */ + private final boolean isQueryPhoneNumber; + + /** * Creates an instance of <tt>PhoneNumberContactQuery</tt> by specifying * the parent contact source, the query string to match and the maximum * result contacts to return. @@ -63,6 +68,10 @@ public class PhoneNumberContactQuery this.queryString = queryString; this.contactCount = contactCount; + + this.isQueryPhoneNumber + = PNContactSourceActivator.getPhoneNumberI18nService() + .isPhoneNumber(queryString); } /** @@ -204,7 +213,13 @@ public class PhoneNumberContactQuery if(StringUtils.isNullOrEmpty(queryString) || query.matcher(numberString).find() || query.matcher(contactName).find() - || query.matcher(contactAddress).find()) + || query.matcher(contactAddress).find() + || (isQueryPhoneNumber + && PNContactSourceActivator + .getPhoneNumberI18nService() + .phoneNumbersMatch( + queryString, numberString)) + ) { ArrayList<ContactDetail> contactDetails = new ArrayList<ContactDetail>(); diff --git a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java index d6a9c58..7dc43d7 100644 --- a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java +++ b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdActivator.java @@ -10,6 +10,7 @@ import java.util.*; import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.configuration.*;
@@ -32,6 +33,11 @@ public class ThunderbirdActivator registrations;
/**
+ * The registered PhoneNumberI18nService.
+ */
+ private static PhoneNumberI18nService phoneNumberI18nService;
+
+ /**
* Gets the configuration service.
* @return the configuration service.
*/
@@ -148,4 +154,20 @@ public class ThunderbirdActivator registrations = null;
}
+
+ /**
+ * Returns the PhoneNumberI18nService.
+ * @return returns the PhoneNumberI18nService.
+ */
+ public static PhoneNumberI18nService getPhoneNumberI18nService()
+ {
+ if(phoneNumberI18nService == null)
+ {
+ phoneNumberI18nService = ServiceUtils.getService(
+ bundleContext,
+ PhoneNumberI18nService.class);
+ }
+
+ return phoneNumberI18nService;
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java index 1c10bba..a3f17d4 100644 --- a/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java +++ b/src/net/java/sip/communicator/plugin/thunderbird/ThunderbirdContactQuery.java @@ -234,7 +234,8 @@ public class ThunderbirdContactQuery return;
}
- phone = PhoneNumberI18nService.normalize(phone);
+ phone
+ = ThunderbirdActivator.getPhoneNumberI18nService().normalize(phone);
ContactDetail detail =
new ContactDetail(phone, ContactDetail.Category.Phone,
new ContactDetail.SubCategory[]
diff --git a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java index 21fa13c..c939ff9 100644 --- a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java +++ b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java @@ -153,7 +153,7 @@ public abstract class AsyncContactQuery<T extends ContactSourceService> */
protected String getPhoneNumberQuery()
{
- if ((phoneNumberQuery != null) && !queryIsConvertedToPhoneNumber)
+ if ((phoneNumberQuery == null) && !queryIsConvertedToPhoneNumber)
{
try
{
@@ -170,6 +170,16 @@ public abstract class AsyncContactQuery<T extends ContactSourceService> phoneNumberQuery
= pattern.substring(1, patternLength - 1);
}
+ else if ((patternLength > 4)
+ && (pattern.charAt(0) == '\\')
+ && (pattern.charAt(1) == 'Q')
+ && (pattern.charAt(patternLength - 2) == '\\')
+ && (pattern.charAt(patternLength - 1) == 'E'))
+ {
+ phoneNumberQuery
+ = pattern.substring(2, patternLength - 2);
+ }
+
}
}
finally
@@ -304,8 +314,8 @@ public abstract class AsyncContactQuery<T extends ContactSourceService> boolean phoneNumberMatches = false;
if (query
- .matcher(PhoneNumberI18nService.normalize(phoneNumber))
- .find())
+ .matcher(ContactSourceActivator.getPhoneNumberI18nService()
+ .normalize(phoneNumber)).find())
{
phoneNumberMatches = true;
}
@@ -330,7 +340,8 @@ public abstract class AsyncContactQuery<T extends ContactSourceService> try
{
phoneNumberMatches
- = PhoneNumberI18nService.phoneNumbersMatch(
+ = ContactSourceActivator.getPhoneNumberI18nService()
+ .phoneNumbersMatch(
phoneNumberQuery,
phoneNumber);
}
diff --git a/src/net/java/sip/communicator/service/contactsource/ContactSourceActivator.java b/src/net/java/sip/communicator/service/contactsource/ContactSourceActivator.java new file mode 100644 index 0000000..77f1bad --- /dev/null +++ b/src/net/java/sip/communicator/service/contactsource/ContactSourceActivator.java @@ -0,0 +1,57 @@ +/* + * 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.service.contactsource; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; +import org.osgi.framework.*; + +/** + * @author Damian Minkov + */ +public class ContactSourceActivator + implements BundleActivator +{ + /** + * OSGi bundle context. + */ + public static BundleContext bundleContext; + + /** + * The registered PhoneNumberI18nService. + */ + private static PhoneNumberI18nService phoneNumberI18nService; + + + @Override + public void start(BundleContext bundleContext) + throws Exception + { + this.bundleContext = bundleContext; + } + + @Override + public void stop(BundleContext bundleContext) + throws Exception + {} + + /** + * Returns the PhoneNumberI18nService. + * @return returns the PhoneNumberI18nService. + */ + public static PhoneNumberI18nService getPhoneNumberI18nService() + { + if(phoneNumberI18nService == null) + { + phoneNumberI18nService = ServiceUtils.getService( + bundleContext, + PhoneNumberI18nService.class); + } + + return phoneNumberI18nService; + } +} diff --git a/src/net/java/sip/communicator/service/contactsource/contactsource.manifest.mf b/src/net/java/sip/communicator/service/contactsource/contactsource.manifest.mf index e70e32c..f14c42d 100644 --- a/src/net/java/sip/communicator/service/contactsource/contactsource.manifest.mf +++ b/src/net/java/sip/communicator/service/contactsource/contactsource.manifest.mf @@ -1,4 +1,5 @@ -Bundle-Name: Contact Source Service Interfaces +Bundle-Activator: net.java.sip.communicator.service.contactsource.ContactSourceActivator +Bundle-Name: Contact Source Service Interfaces Bundle-Description: ContactSource Service. Bundle-Vendor: jitsi.org Bundle-Version: 0.0.1 diff --git a/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java b/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java index 4ca060d..2ee195b 100644 --- a/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java +++ b/src/net/java/sip/communicator/service/protocol/PhoneNumberI18nService.java @@ -6,87 +6,17 @@ */
package net.java.sip.communicator.service.protocol;
-import java.util.regex.*;
-
-import org.jitsi.service.configuration.*;
-
/**
* Implements <tt>PhoneNumberI18nService</tt> which aids the parsing, formatting
* and validating of international phone numbers.
*
* @author Lyubomir Marinov
* @author Vincent Lucas
+ * @author Damian Minkov
*/
-public abstract class PhoneNumberI18nService
+public interface PhoneNumberI18nService
{
/**
- * The configuration service.
- */
- private static ConfigurationService configService
- = ProtocolProviderActivator.getConfigurationService();
-
- /**
- * Characters which have to be removed from a phone number in order to
- * normalized it.
- */
- private static final Pattern removedCharactersToNormalizedPhoneNumber
- = Pattern.compile("[-\\(\\)\\.\\\\\\/ ]");
-
- /**
- * Characters which have to be removed from a number (which is not a phone
- * number, such as a sip id, a jabber id, etc.) in order to normalized it.
- */
- private static final Pattern removedCharactersToNormalizedIdentifier
- = Pattern.compile("[\\(\\) ]");
-
- /**
- * The list of characters corresponding to the number 2 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber2
- = Pattern.compile("[abc]", Pattern.CASE_INSENSITIVE);
- /**
- * The list of characters corresponding to the number 3 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber3
- = Pattern.compile("[def]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 4 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber4
- = Pattern.compile("[ghi]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 5 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber5
- = Pattern.compile("[jkl]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 6 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber6
- = Pattern.compile("[mno]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 7 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber7
- = Pattern.compile("[pqrs]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 8 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber8
- = Pattern.compile("[tuv]", Pattern.CASE_INSENSITIVE);
-
- /**
- * The list of characters corresponding to the number 9 in a phone dial pad.
- */
- private static final Pattern charactersFordialPadNumber9
- = Pattern.compile("[wxyz]", Pattern.CASE_INSENSITIVE);
-
- /**
* Normalizes a <tt>String</tt> which may be a phone number or a identifier
* by removing useless characters and, if necessary, replacing the alpahe
* characters in corresponding dial pad numbers.
@@ -97,56 +27,7 @@ public abstract class PhoneNumberI18nService * @return a <tt>String</tt> which is a normalized form of the specified
* <tt>possibleNumber</tt>.
*/
- public static String normalize(String possibleNumber)
- {
- String normalizedNumber;
- if(isPhoneNumber(possibleNumber))
- {
- normalizedNumber = normalizePhoneNumber(possibleNumber);
- }
- else
- {
- normalizedNumber = normalizeIdentifier(possibleNumber);
- }
-
- return normalizedNumber;
- }
-
-
- /**
- * Normalizes a <tt>String</tt> phone number by converting alpha characters
- * to their respective digits on a keypad and then stripping non-digit
- * characters.
- *
- * @param phoneNumber a <tt>String</tt> which represents a phone number to
- * normalize
- *
- * @return a <tt>String</tt> which is a normalized form of the specified
- * <tt>phoneNumber</tt>
- *
- * @see PhoneNumberI18nService#normalize(String)
- */
- private static String normalizePhoneNumber(String phoneNumber)
- {
- phoneNumber = convertAlphaCharactersInNumber(phoneNumber);
- return removedCharactersToNormalizedPhoneNumber
- .matcher(phoneNumber).replaceAll("");
- }
-
- /**
- * Removes useless characters from a identifier (which is not a phone
- * number) in order to normalized it.
- *
- * @param id The identifier string with some useless characters like: " ",
- * "(", ")".
- *
- * @return The normalized identifier.
- */
- private static String normalizeIdentifier(String id)
- {
- return removedCharactersToNormalizedIdentifier
- .matcher(id).replaceAll("");
- }
+ public String normalize(String possibleNumber);
/**
* Determines whether two <tt>String</tt> phone numbers match.
@@ -158,15 +39,7 @@ public abstract class PhoneNumberI18nService * @return <tt>true</tt> if the specified <tt>String</tt>s match as phone
* numbers; otherwise, <tt>false</tt>
*/
- public static boolean phoneNumbersMatch(
- String aPhoneNumber,
- String bPhoneNumber)
- {
- String aPhoneNumberNormalized = normalize(aPhoneNumber);
- String bPhoneNumberNormalized = normalize(bPhoneNumber);
-
- return aPhoneNumberNormalized.equals(bPhoneNumberNormalized);
- }
+ public boolean phoneNumbersMatch(String aPhoneNumber, String bPhoneNumber);
/**
* Indicates if the given string is possibly a phone number.
@@ -175,64 +48,5 @@ public abstract class PhoneNumberI18nService * @return <tt>true</tt> if the possibleNumber is a phone number,
* <tt>false</tt> - otherwise
*/
- public static boolean isPhoneNumber(String possibleNumber)
- {
- // If the string does not contains an "@", this may be a phone number.
- if(possibleNumber.indexOf('@') == -1)
- {
- // If the string does not contain any alphabetical characters, then
- // this is a phone number.
- if(!possibleNumber.matches(".*[a-zA-Z].*"))
- {
- return true;
- }
- else
- {
- // Removes the " ", "(" and ")" in order to search the "+"
- // character at the beginning at the string.
- String tmpPossibleNumber
- = possibleNumber.replaceAll(" \\(\\)", "");
- // If the property is enabled and the string starts with a "+",
- // then we consider that this is a phone number.
- if(configService.getBoolean(
- "impl.gui.ACCEPT_PHONE_NUMBER_WITH_ALPHA_CHARS",
- true)
- && tmpPossibleNumber.startsWith("+"))
- {
- return true;
- }
- }
- }
- // Else the string is not a phone number.
- return false;
- }
-
- /**
- * Changes all alphabetical characters into numbers, following phone dial
- * pad disposition.
- *
- * @param phoneNumber The phone number string with some alphabetical
- * characters.
- *
- * @return The phone number with all alphabetical caracters replaced with
- * the corresponding dial pad number.
- */
- private static String convertAlphaCharactersInNumber(String phoneNumber)
- {
- phoneNumber
- = charactersFordialPadNumber2.matcher(phoneNumber).replaceAll("2");
- phoneNumber
- = charactersFordialPadNumber3.matcher(phoneNumber).replaceAll("3");
- phoneNumber
- = charactersFordialPadNumber4.matcher(phoneNumber).replaceAll("4");
- phoneNumber
- = charactersFordialPadNumber5.matcher(phoneNumber).replaceAll("5");
- phoneNumber
- = charactersFordialPadNumber6.matcher(phoneNumber).replaceAll("6");
- phoneNumber
- = charactersFordialPadNumber7.matcher(phoneNumber).replaceAll("7");
- phoneNumber
- = charactersFordialPadNumber8.matcher(phoneNumber).replaceAll("8");
- return charactersFordialPadNumber9.matcher(phoneNumber).replaceAll("9");
- }
+ public boolean isPhoneNumber(String possibleNumber);
}
|