/*
* 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.protocol.icq;
import java.io.*;
import java.util.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.BirthDateDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.CountryDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenericDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.ImageDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.SpokenLanguageDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.StringDetail;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import net.kano.joscar.*;
import net.kano.joscar.snac.*;
import net.kano.joscar.snaccmd.*;
import net.kano.joscar.snaccmd.icq.*;
import net.kano.joustsim.*;
import net.kano.joustsim.oscar.oscar.service.icon.*;
/**
* @author Damian Minkov
*/
public class OperationSetServerStoredAccountInfoIcqImpl
extends AbstractOperationSetServerStoredAccountInfo
{
private static final Logger logger =
Logger.getLogger(OperationSetServerStoredAccountInfoIcqImpl.class);
private InfoRetreiver infoRetreiver = null;
private String uin = null;
/**
* The icq provider that created us.
*/
private ProtocolProviderServiceIcqImpl icqProvider = null;
// public static final IcqType CMD_SET_FULLINFO = new IcqType(0x07D0, 0x0c3a);
private int reqID = 0;
// the value is int[]
// int[0] - the max count of this detail
// the Tlv type for this detail
public static final Map<Class<? extends GenericDetail>, int[]> supportedTypes
= new Hashtable<Class<? extends GenericDetail>, int[]>();
static {
supportedTypes.put(ServerStoredDetails.CountryDetail.class, new int[]{1, 0x01A4});
supportedTypes.put(ServerStoredDetails.NicknameDetail.class, new int[]{1, 0x0154});
supportedTypes.put(ServerStoredDetails.FirstNameDetail.class, new int[]{1, 0x0140});
supportedTypes.put(ServerStoredDetails.LastNameDetail.class, new int[]{1, 0x014A});
supportedTypes.put(ServerStoredDetails.EmailAddressDetail.class, new int[]{5, 0x015E});
supportedTypes.put(ServerStoredDetails.CityDetail.class, new int[]{1, 0x0190});
supportedTypes.put(ServerStoredDetails.ProvinceDetail.class, new int[]{1, 0x019A});
supportedTypes.put(ServerStoredDetails.PhoneNumberDetail.class, new int[]{1, 0x0276});
supportedTypes.put(ServerStoredDetails.FaxDetail.class, new int[]{1, 0x0280});
supportedTypes.put(ServerStoredDetails.AddressDetail.class, new int[]{1, 0x0262});
supportedTypes.put(ServerStoredDetails.MobilePhoneDetail.class, new int[]{1, 0x028A});
supportedTypes.put(ServerStoredDetails.PostalCodeDetail.class, new int[]{1, 0x026C});
supportedTypes.put(ServerStoredDetails.GenderDetail.class, new int[]{1, 0x017C});
supportedTypes.put(ServerStoredDetails.WebPageDetail.class, new int[]{1, 0x0213});
supportedTypes.put(ServerStoredDetails.BirthDateDetail.class, new int[]{1, 0x023A});
supportedTypes.put(ServerStoredDetails.SpokenLanguageDetail.class, new int[]{3, 0x0186});
supportedTypes.put(OriginCityDetail.class, new int[]{1, 0x0320});
supportedTypes.put(OriginProvinceDetail.class, new int[]{1, 0x032A});
supportedTypes.put(OriginCountryDetail.class, new int[]{1, 0x0334});
supportedTypes.put(ServerStoredDetails.WorkCityDetail.class, new int[]{1, 0x029E});
supportedTypes.put(ServerStoredDetails.WorkProvinceDetail.class, new int[]{1, 0x02A8});
supportedTypes.put(ServerStoredDetails.WorkPhoneDetail.class, new int[]{1, 0x02C6});
supportedTypes.put(WorkFaxDetail.class, new int[]{1, 0x02D0});
supportedTypes.put(ServerStoredDetails.WorkAddressDetail.class, new int[]{1, 0x0294});
supportedTypes.put(ServerStoredDetails.WorkPostalCodeDetail.class, new int[]{1, 0x02BC});
supportedTypes.put(ServerStoredDetails.WorkCountryDetail.class, new int[]{1, 0x02B2});
supportedTypes.put(ServerStoredDetails.WorkOrganizationNameDetail.class, new int[]{1, 0x01AE});
supportedTypes.put(WorkDepartmentNameDetail.class, new int[]{1, 0x01B8});
supportedTypes.put(WorkPositionNameDetail.class, new int[]{1, 0x01C2});
supportedTypes.put(WorkOcupationDetail.class, new int[]{1, 0x01CC});
supportedTypes.put(ServerStoredDetails.WorkPageDetail.class, new int[]{1, 0x02DA});
supportedTypes.put(NotesDetail.class, new int[]{1, 0x0258});
supportedTypes.put(InterestDetail.class, new int[]{10, 0x01EA});
supportedTypes.put(ServerStoredDetails.TimeZoneDetail.class, new int[]{1, 0x0316});
}
/**
* Our image.
*/
private ImageDetail accountImage = null;
/**
* Listener waiting for our image.
*/
private IconUpdateListener iconListener = null;
/**
* Creates instance of OperationSetServerStoredAccountInfo
* for icq protocol.
* @param infoRetreiver the info retreiver
* @param uin our own account uin
* @param icqProvider the provider
*/
public OperationSetServerStoredAccountInfoIcqImpl
(InfoRetreiver infoRetreiver, String uin,
ProtocolProviderServiceIcqImpl icqProvider)
{
this.infoRetreiver = infoRetreiver;
this.uin = uin;
this.icqProvider = icqProvider;
}
/**
* Returns all details currently available and set for our account.
*
* @return a java.util.Iterator over all details currently set our
* account.
*/
public Iterator<GenericDetail> getAllAvailableDetails()
{
assertConnected();
List<GenericDetail> ds = infoRetreiver.getContactDetails(uin);
GenericDetail img = getImage();
if(img != null)
ds.add(img);
return ds.iterator();
}
/**
* Returns an iterator over all details that are instances of exactly the
* same class as the one specified.
*
* @param detailClass one of the detail classes defined in the
* ServerStoredDetails class, indicating the kind of details we're
* interested in. <p>
* @return a java.util.Iterator over all details of specified class.
*/
public Iterator<GenericDetail> getDetails(
Class<? extends GenericDetail> detailClass)
{
assertConnected();
if(detailClass.equals(ImageDetail.class))
{
List<GenericDetail> res = new Vector<GenericDetail>();
res.add(getImage());
return res.iterator();
}
return infoRetreiver.getDetails(uin, detailClass);
}
/**
* Returns an iterator over all details that are instances or descendants
* of the specified class.
*
* @param detailClass one of the detail classes defined in the
* ServerStoredDetails class, indicating the kind of details we're
* interested in. <p>
* @return a java.util.Iterator over all details that are instances or
* descendants of the specified class.
*/
public <T extends GenericDetail> Iterator<T> getDetailsAndDescendants(
Class<T> detailClass)
{
assertConnected();
if(ImageDetail.class.isAssignableFrom(detailClass))
{
List<ImageDetail> res = new Vector<ImageDetail>();
res.add(getImage());
@SuppressWarnings("unchecked")
Iterator<T> tIt = (Iterator<T>) res.iterator();
return tIt;
}
return infoRetreiver.getDetailsAndDescendants(uin, detailClass);
}
/**
* The method returns the number of instances supported for a particular
* detail type.
*
* @param detailClass the class whose max instance number we'd like to
* find out. <p>
* @return int the maximum number of detail instances.
*/
public int getMaxDetailInstances(Class<? extends GenericDetail> detailClass)
{
return supportedTypes.get(detailClass)[0];
}
/**
* Returns all detail Class-es that the underlying implementation
* supports setting.
*
* @return a java.util.Iterator over all detail classes supported by the
* implementation.
*/
public Iterator<Class<? extends GenericDetail>> getSupportedDetailTypes()
{
return supportedTypes.keySet().iterator();
}
/**
* Determines whether a detail class represents a detail supported by the
* underlying implementation or not.
*
* @param detailClass the class the support for which we'd like to
* determine. <p>
* @return true if the underlying implementation supports setting
* details of this type and false otherwise.
*/
public boolean isDetailClassSupported(
Class<? extends GenericDetail> detailClass)
{
return supportedTypes.get(detailClass) != null;
}
/**
* Utility method throwing an exception if the icq stack is not properly
* initialized.
* @throws java.lang.IllegalStateException if the underlying ICQ stack is
* not registered and initialized.
*/
private void assertConnected() throws IllegalStateException
{
if (icqProvider == null)
throw new IllegalStateException(
"The icq provider must be non-null and signed on the ICQ "
+"service before being able to communicate.");
if (!icqProvider.isRegistered())
throw new IllegalStateException(
"The icq provider must be signed on the ICQ service before "
+"being able to communicate.");
}
/**
* Adds the specified detail to the list of details registered on-line
* for this account. If such a detail already exists its max instance number
* is consulted and if it allows it - a second instance is added or otherwise
* and illegal argument exception is thrown. An IllegalArgumentException is
* also thrown in case the class of the specified detail is not supported by
* the underlying implementation, i.e. its class name was not returned by the
* getSupportedDetailTypes() method.
* <p>
* @param detail the detail that we'd like registered on the server.
* <p>
* @throws IllegalArgumentException if such a detail already exists and its
* max instances number has been atteined or if the underlying
* implementation does not support setting details of the corresponding
* class.
* @throws OperationFailedException with code Network Failure if putting the
* new value online has failed
* @throws java.lang.ArrayIndexOutOfBoundsException if the number of
* instances currently registered by the application is already equal to the
* maximum number of supported instances (@see getMaxDetailInstances())
*/
public void addDetail(GenericDetail detail) throws IllegalArgumentException,
OperationFailedException, ArrayIndexOutOfBoundsException
{
assertConnected();
if(!isDetailClassSupported(detail.getClass()))
throw new IllegalArgumentException(
"implementation does not support such details " +
detail.getClass());
List<GenericDetail> alreadySetDetails = new Vector<GenericDetail>();
Iterator<GenericDetail> iter = getDetails(detail.getClass());
while (iter.hasNext())
{
alreadySetDetails.add(iter.next());
}
if(alreadySetDetails.size() >= getMaxDetailInstances(detail.getClass()))
throw new ArrayIndexOutOfBoundsException(
"Max count for this detail is already reached");
if (detail instanceof ImageDetail)
{
if (iconListener == null)
{
iconListener = new IconUpdateListener();
this.icqProvider.getAimConnection().getExternalServiceManager().
getIconServiceArbiter().addIconRequestListener(
new IconUpdateListener());
}
icqProvider.getAimConnection().getMyBuddyIconManager().requestSetIcon(
ByteBlock.wrap(((ServerStoredDetails.ImageDetail) detail).getBytes()));
infoRetreiver.detailsChanged(uin);
fireServerStoredDetailsChangeEvent(icqProvider,
ServerStoredDetailsChangeEvent.DETAIL_ADDED,
null,
detail);
return;
}
// everything is ok , so set it
alreadySetDetails.add(detail);
SuccessResponseListener responseListener = new SuccessResponseListener();
MetaFullInfoSetCmd cmd =
new MetaFullInfoSetCmd(Integer.parseInt(uin), reqID++);
int typeOfDetail =
supportedTypes.get(detail.getClass())[1];
try
{
switch(typeOfDetail)
{
case 0x01A4 : cmd.setCountry(getCountryCode(((CountryDetail)detail).getLocale())); break;
case 0x0154 : cmd.setNickName(((StringDetail)detail).getString()); break;
case 0x0140 : cmd.setFirstName(((StringDetail)detail).getString()); break;
case 0x014A : cmd.setLastName(((StringDetail)detail).getString()); break;
case 0x015E : cmd.setEmail(((StringDetail)detail).getString(), false); break;
case 0x0190 : cmd.setHomeCity(((StringDetail)detail).getString()); break;
case 0x019A : cmd.setHomeState(((StringDetail)detail).getString()); break;
case 0x0276 : cmd.setHomePhone(((StringDetail)detail).getString()); break;
case 0x0280 : cmd.setHomeFax(((StringDetail)detail).getString()); break;
case 0x0262 : cmd.setAddress(((StringDetail)detail).getString()); break;
case 0x028A : cmd.setCellPhone(((StringDetail)detail).getString()); break;
case 0x026C : cmd.setHomeZip(((StringDetail)detail).getString()); break;
case 0x017C :
if(detail.equals(ServerStoredDetails.GenderDetail.FEMALE))
cmd.setGender(1);
else if(detail.equals(ServerStoredDetails.GenderDetail.MALE))
cmd.setGender(2);
else
cmd.setGender(0); break;
case 0x0213 : cmd.setHomePage(((StringDetail)detail).getString()); break;
case 0x023A : cmd.setBirthDay(((BirthDateDetail)detail).getCalendar().getTime()); break;
case 0x0186 :
int[] langs = new int[3];
Arrays.fill(langs, -1);
int count = 0;
Iterator<GenericDetail> i
= getDetails(SpokenLanguageDetail.class);
while (i.hasNext())
{
GenericDetail item = i.next();
langs[count++]
= getLanguageCode(
((SpokenLanguageDetail)item).getLocale());
}
langs[count] = getLanguageCode(((SpokenLanguageDetail)detail).getLocale());
cmd.setLanguages(langs[0], langs[1], langs[2]);
break;
case 0x0320 : cmd.setOriginCity(((StringDetail)detail).getString()); break;
case 0x032A : cmd.setOriginState(((StringDetail)detail).getString()); break;
case 0x0334 : cmd.setOriginCountry(getCountryCode(((CountryDetail)detail).getLocale())); break;
case 0x029E : cmd.setWorkCity(((StringDetail)detail).getString()); break;
case 0x02A8 : cmd.setWorkState(((StringDetail)detail).getString()); break;
case 0x02C6 : cmd.setWorkPhone(((StringDetail)detail).getString()); break;
case 0x02D0 : cmd.setWorkFax(((StringDetail)detail).getString()); break;
case 0x0294 : cmd.setWorkAddress(((StringDetail)detail).getString()); break;
case 0x02BC : cmd.setWorkZip(((StringDetail)detail).getString()); break;
case 0x02B2 : cmd.setWorkCountry(getCountryCode(((CountryDetail)detail).getLocale())); break;
case 0x01AE : cmd.setWorkCompany(((StringDetail)detail).getString()); break;
case 0x01B8 : cmd.setWorkDepartment(((StringDetail)detail).getString()); break;
case 0x01C2 : cmd.setWorkPosition(((StringDetail)detail).getString()); break;
case 0x01CC :
cmd.setWorkOccupationCode(getOccupationCode(((StringDetail)detail).getString())); break;
case 0x02DA : cmd.setWorkWebPage(((StringDetail)detail).getString()); break;
case 0x0258 : cmd.setNotes(((StringDetail)detail).getString()); break;
case 0x01EA :
List<InterestDetail> interests = new ArrayList<InterestDetail>();
Iterator<GenericDetail> intIter
= getDetails(InterestDetail.class);
while (intIter.hasNext())
{
InterestDetail item = (InterestDetail) intIter.next();
interests.add(item);
}
setInterests(cmd, interests);
break;
case 0x0316 :
int offset = ((ServerStoredDetails.TimeZoneDetail)detail).
getTimeZone().getRawOffset()/(60*60*1000);
cmd.setTimeZone(offset);
break;
}
}
catch(IOException ex)
{
throw new OperationFailedException("Cannot add Detail!",
OperationFailedException.NETWORK_FAILURE);
}
icqProvider.getAimConnection().getInfoService().getOscarConnection().
sendSnacRequest(cmd, responseListener);
responseListener.waitForEvent(5000);
if(!responseListener.success)
if(responseListener.timeout)
throw new OperationFailedException("Adding Detail Failed!",
OperationFailedException.NETWORK_FAILURE);
else
throw new OperationFailedException("Adding Detail Failed!",
OperationFailedException.GENERAL_ERROR);
infoRetreiver.detailsChanged(uin);
fireServerStoredDetailsChangeEvent(icqProvider,
ServerStoredDetailsChangeEvent.DETAIL_ADDED,
null,
detail);
}
private void setInterests(MetaFullInfoSetCmd cmd, List<InterestDetail> interests)
throws IOException
{
int interestCount = interests.size();
int[] interestsCategories = new int[interestCount];
String[] interestsStr = new String[interestCount];
for (int k = 0; k < interestCount; k++)
{
interestsStr[k] = interests.get(k).getInterest();
interestsCategories[k] = getInterestCode(interestsStr[k]);
}
cmd.setInterests(interestsCategories, interestsStr);
}
/**
* Removes the specified detail from the list of details stored online
* for this account.
*
* @param detail the detail to remove
* @return true if the specified detail existed and was successfully
* removed and false otherwise.
* @throws OperationFailedException with code Network Failure if
* removing the detail from the server has failed
*/
public boolean removeDetail(GenericDetail detail) throws
OperationFailedException
{
assertConnected();
// as there is no remove method for the details we will
// set it with empty or default value
boolean isFound = false;
// as there is items like language, which must be changed all the values
// we write not only the changed one but and the other found
List<GenericDetail> foundValues = new ArrayList<GenericDetail>();
Iterator<?> iter = infoRetreiver.getDetails(uin, detail.getClass());
while (iter.hasNext())
{
GenericDetail item = (GenericDetail) iter.next();
if(item.equals(detail))
{
isFound = true;
foundValues.add(detail);
}
else
foundValues.add(item);
}
// current detail value does not exist
if(!isFound)
return false;
SuccessResponseListener responseListener = new SuccessResponseListener();
MetaFullInfoSetCmd cmd =
new MetaFullInfoSetCmd(Integer.parseInt(uin), reqID++);
int typeOfDetail =
supportedTypes.get(detail.getClass())[1];
try
{
switch(typeOfDetail)
{
case 0x01A4 : cmd.setCountry(-1); break;
case 0x0154 : cmd.setNickName(null); break;
case 0x0140 : cmd.setFirstName(null); break;
case 0x014A : cmd.setLastName(null); break;
case 0x015E : cmd.setEmail(null, false); break;
case 0x0190 : cmd.setHomeCity(null); break;
case 0x019A : cmd.setHomeState(null); break;
case 0x0276 : cmd.setHomePhone(null); break;
case 0x0280 : cmd.setHomeFax(null); break;
case 0x0262 : cmd.setAddress(null); break;
case 0x028A : cmd.setCellPhone(null); break;
case 0x026C : cmd.setHomeZip(null); break;
case 0x017C : cmd.setGender(0);break;
case 0x0213 : cmd.setHomePage(null); break;
case 0x023A : cmd.setBirthDay(null); break;
case 0x0186 :
int[] langs = new int[3];
Arrays.fill(langs, -1);
cmd.setLanguages(langs[0], langs[1], langs[2]);
break;
case 0x0320 : cmd.setOriginCity(null); break;
case 0x032A : cmd.setOriginState(null); break;
case 0x0334 : cmd.setOriginCountry(-1); break;
case 0x029E : cmd.setWorkCity(null); break;
case 0x02A8 : cmd.setWorkState(null); break;
case 0x02C6 : cmd.setWorkPhone(null); break;
case 0x02D0 : cmd.setWorkFax(null); break;
case 0x0294 : cmd.setWorkAddress(null); break;
case 0x02BC : cmd.setWorkZip(null); break;
case 0x02B2 : cmd.setWorkCountry(-1); break;
case 0x01AE : cmd.setWorkCompany(null); break;
case 0x01B8 : cmd.setWorkDepartment(null); break;
case 0x01C2 : cmd.setWorkPosition(null); break;
case 0x01CC : cmd.setWorkOccupationCode(0);break;
case 0x02DA : cmd.setWorkWebPage(null); break;
case 0x0258 : cmd.setNotes(null); break;
case 0x01EA : cmd.setInterests(new int[]{0}, new String[]{""}); break;
case 0x0316 : cmd.setTimeZone(0); break;
}
}
catch (IOException ex)
{
throw new OperationFailedException("Cannot add Detail!",
OperationFailedException.NETWORK_FAILURE);
}
icqProvider.getAimConnection().getInfoService().getOscarConnection().
sendSnacRequest(cmd, responseListener);
responseListener.waitForEvent(5000);
if (!responseListener.success && responseListener.timeout)
throw new OperationFailedException("Replacing Detail Failed!",
OperationFailedException.
NETWORK_FAILURE);
if (responseListener.success)
{
infoRetreiver.detailsChanged(uin);
fireServerStoredDetailsChangeEvent(icqProvider,
ServerStoredDetailsChangeEvent.DETAIL_REMOVED,
detail,
null);
return true;
}
else
return false;
}
/**
* Replaces the currentDetailValue detail with newDetailValue and returns
* true if the operation was a success or false if currentDetailValue did
* not previously exist (in this case an additional call to addDetail is
* required).
*
* @param currentDetailValue the detail value we'd like to replace.
* @param newDetailValue the value of the detail that we'd like to
* replace currentDetailValue with.
* @throws ClassCastException if newDetailValue is not an instance of
* the same class as currentDetailValue.
* @throws OperationFailedException with code Network Failure if putting
* the new value back online has failed
* @return boolean
*/
public boolean replaceDetail(GenericDetail currentDetailValue,
GenericDetail newDetailValue) throws
ClassCastException, OperationFailedException
{
assertConnected();
if(!newDetailValue.getClass().equals(currentDetailValue.getClass()))
throw new ClassCastException("New value to be replaced is not as the current one");
// if values are the same no change
if(currentDetailValue.equals(newDetailValue))
return true;
boolean isFound = false;
List<GenericDetail> alreadySetDetails = new Vector<GenericDetail>();
Iterator<GenericDetail> iter
= infoRetreiver.getDetails(uin, currentDetailValue.getClass());
while (iter.hasNext())
{
GenericDetail item = iter.next();
if(item.equals(currentDetailValue))
{
isFound = true;
// add the details to the list. We will save the list on one pass
// most of the multiple details require saving at one time, like Spoken Language
// we are placing it at the right place. replacing the old one
alreadySetDetails.add(newDetailValue);
}
else
alreadySetDetails.add(item);
}
// current detail value does not exist
if(!isFound)
return false;
//replacing in case of image
if (newDetailValue instanceof ImageDetail)
{
if (iconListener == null)
{
iconListener = new IconUpdateListener();
this.icqProvider.getAimConnection().getExternalServiceManager().
getIconServiceArbiter().addIconRequestListener(
new IconUpdateListener());
}
icqProvider.getAimConnection().getMyBuddyIconManager()
.requestSetIcon(ByteBlock.wrap(
((ServerStoredDetails.ImageDetail) newDetailValue)
.getBytes()));
infoRetreiver.detailsChanged(uin);
fireServerStoredDetailsChangeEvent(icqProvider,
ServerStoredDetailsChangeEvent.DETAIL_REPLACED,
currentDetailValue,
newDetailValue);
return true;
}
SuccessResponseListener responseListener = new SuccessResponseListener();
// // if toBeCleared == null. make it empty one
// if(toBeCleared == null)
// toBeCleared = new ArrayList();
//
// // fix the spoken languages must be 3
// int lastSpokenIndex = -1;
// int countOfLanguages = 0;
// boolean isLanguageFound = false;
// for(int i = 0; i < changedData.size(); i++)
// {
// Object item = changedData.get(i);
// if(item instanceof ServerStoredDetails.SpokenLanguageDetail)
// {
// isLanguageFound = true;
// lastSpokenIndex = i;
// countOfLanguages++;
// }
// }
//
// if(isLanguageFound)
// {
// for (int i = countOfLanguages; i < 3; i++)
// {
// lastSpokenIndex++;
// changedData.add(lastSpokenIndex,
// new ServerStoredDetails.SpokenLanguageDetail(null));
// }
// }
//
// Iterator iter = changedData.iterator();
// while(iter.hasNext())
// {
// ServerStoredDetails.GenericDetail item =
// (ServerStoredDetails.GenericDetail)iter.next();
//
// if(toBeCleared.contains(item))
// changeDataTlvs.add(getClearTlv(item));
// else
// changeDataTlvs.add(getTlvForChange(item));
// }
MetaFullInfoSetCmd cmd =
new MetaFullInfoSetCmd(Integer.parseInt(uin), reqID++);
int typeOfDetail =
supportedTypes.get(newDetailValue.getClass())[1];
try
{
switch(typeOfDetail)
{
case 0x01A4 : cmd.setCountry(getCountryCode(((CountryDetail)newDetailValue).getLocale())); break;
case 0x0154 : cmd.setNickName(((StringDetail)newDetailValue).getString()); break;
case 0x0140 : cmd.setFirstName(((StringDetail)newDetailValue).getString()); break;
case 0x014A :
cmd.setLastName(((StringDetail)newDetailValue).getString()); break;
case 0x015E : cmd.setEmail(((StringDetail)newDetailValue).getString(), false); break;
case 0x0190 : cmd.setHomeCity(((StringDetail)newDetailValue).getString()); break;
case 0x019A : cmd.setHomeState(((StringDetail)newDetailValue).getString()); break;
case 0x0276 : cmd.setHomePhone(((StringDetail)newDetailValue).getString()); break;
case 0x0280 : cmd.setHomeFax(((StringDetail)newDetailValue).getString()); break;
case 0x0262 : cmd.setAddress(((StringDetail)newDetailValue).getString()); break;
case 0x028A : cmd.setCellPhone(((StringDetail)newDetailValue).getString()); break;
case 0x026C : cmd.setHomeZip(((StringDetail)newDetailValue).getString()); break;
case 0x017C :
if(newDetailValue.equals(ServerStoredDetails.GenderDetail.FEMALE))
cmd.setGender(1);
else if(newDetailValue.equals(ServerStoredDetails.GenderDetail.MALE))
cmd.setGender(2);
else
cmd.setGender(0); break;
case 0x0213 : cmd.setHomePage(((StringDetail)newDetailValue).getString()); break;
case 0x023A : cmd.setBirthDay(((BirthDateDetail)newDetailValue).getCalendar().getTime()); break;
case 0x0186 :
int[] langs = new int[3];
Arrays.fill(langs, -1);
int count = 0;
Iterator<GenericDetail> i = getDetails(SpokenLanguageDetail.class);
while (i.hasNext())
{
GenericDetail item = i.next();
if(item.equals(currentDetailValue))
langs[count++] = getLanguageCode(((SpokenLanguageDetail)newDetailValue).getLocale());
else
langs[count++] = getLanguageCode(((SpokenLanguageDetail)item).getLocale());
}
cmd.setLanguages(langs[0], langs[1], langs[2]);
break;
case 0x0320 : cmd.setOriginCity(((StringDetail)newDetailValue).getString()); break;
case 0x032A : cmd.setOriginState(((StringDetail)newDetailValue).getString()); break;
case 0x0334 : cmd.setOriginCountry(getCountryCode(((CountryDetail)newDetailValue).getLocale())); break;
case 0x029E : cmd.setWorkCity(((StringDetail)newDetailValue).getString()); break;
case 0x02A8 : cmd.setWorkState(((StringDetail)newDetailValue).getString()); break;
case 0x02C6 : cmd.setWorkPhone(((StringDetail)newDetailValue).getString()); break;
case 0x02D0 : cmd.setWorkFax(((StringDetail)newDetailValue).getString()); break;
case 0x0294 : cmd.setWorkAddress(((StringDetail)newDetailValue).getString()); break;
case 0x02BC : cmd.setWorkZip(((StringDetail)newDetailValue).getString()); break;
case 0x02B2 : cmd.setWorkCountry(getCountryCode(((CountryDetail)newDetailValue).getLocale())); break;
case 0x01AE : cmd.setWorkCompany(((StringDetail)newDetailValue).getString()); break;
case 0x01B8 : cmd.setWorkDepartment(((StringDetail)newDetailValue).getString()); break;
case 0x01C2 : cmd.setWorkPosition(((StringDetail)newDetailValue).getString()); break;
case 0x01CC :
cmd.setWorkOccupationCode(getOccupationCode(((StringDetail)newDetailValue).getString())); break;
case 0x02DA : cmd.setWorkWebPage(((StringDetail)newDetailValue).getString()); break;
case 0x0258 : cmd.setNotes(((StringDetail)newDetailValue).getString()); break;
case 0x01EA :
List<InterestDetail> interests
= new ArrayList<InterestDetail>();
Iterator<GenericDetail> intIter
= getDetails(InterestDetail.class);
while (intIter.hasNext())
{
InterestDetail item = (InterestDetail) intIter.next();
if(item.equals(currentDetailValue))
interests.add((InterestDetail) newDetailValue);
else
interests.add(item);
}
setInterests(cmd, interests);
break;
case 0x0316 :
int offset = ((ServerStoredDetails.TimeZoneDetail)newDetailValue).
getTimeZone().getRawOffset()/(60*60*1000);
cmd.setTimeZone(offset);
break;
}
}
catch (IOException ex)
{
throw new OperationFailedException("Cannot add Detail!",
OperationFailedException.NETWORK_FAILURE);
}
icqProvider.getAimConnection().getInfoService().getOscarConnection().
sendSnacRequest(
cmd, responseListener);
responseListener.waitForEvent(5000);
if(!responseListener.success && responseListener.timeout)
throw new OperationFailedException("Replacing Detail Failed!",
OperationFailedException.NETWORK_FAILURE);
if(responseListener.success)
{
infoRetreiver.detailsChanged(uin);
fireServerStoredDetailsChangeEvent(icqProvider,
ServerStoredDetailsChangeEvent.DETAIL_REPLACED,
currentDetailValue,
newDetailValue);
return true;
}
else
return false;
}
/**
* Requests the account image if its missing.
* @return the new image or the one that has been already downloaded.
*/
private ImageDetail getImage()
{
if(accountImage != null)
return accountImage;
if(iconListener == null)
{
iconListener = new IconUpdateListener();
this.icqProvider.getAimConnection().getExternalServiceManager().
getIconServiceArbiter().addIconRequestListener(
new IconUpdateListener());
}
ExtraInfoData infoData =
new ExtraInfoData(
ExtraInfoData.FLAG_HASH_PRESENT,
ByteBlock.EMPTY_BLOCK);
icqProvider.getAimConnection().getExternalServiceManager().
getIconServiceArbiter().requestIcon(new Screenname(uin), infoData);
// now wait image to come
iconListener.waitForImage(22000);
return accountImage;
}
/**
* Waiting for Acknowledge package and success byte.
* To set that the operation was successful
*/
private static class SuccessResponseListener
implements SnacRequestListener
{
public Object waitingForResponseLock = new Object();
private boolean ran = false;
boolean success = false;
private boolean timeout = false;
public void handleSent(SnacRequestSentEvent evt)
{}
public void handleTimeout(SnacRequestTimeoutEvent event)
{
if (logger.isTraceEnabled())
logger.trace("Timeout!");
synchronized(waitingForResponseLock)
{
if (ran)
return;
ran = true;
timeout = true;
waitingForResponseLock.notifyAll();
}
}
public void handleResponse(SnacResponseEvent evt)
{
synchronized(waitingForResponseLock)
{
if (ran)
return;
ran = true;
if (evt.getSnacCommand() instanceof MetaFullInfoAckCmd)
{
MetaFullInfoAckCmd cmd = (MetaFullInfoAckCmd) evt.getSnacCommand();
if (cmd.isCommandSuccesful())
success = true;
}
waitingForResponseLock.notifyAll();
}
}
public void waitForEvent(int milliseconds)
{
synchronized (waitingForResponseLock){
if(ran)
return;
try
{
waitingForResponseLock.wait(milliseconds);
}
catch (InterruptedException exc)
{
logger.error("Interrupted while waiting for response."
, exc);
}
}
}
}
/**
* Our format data
*/
/**
* Returns the Locale corresponding the index coming from icq server
*
* @param code int
* @return Locale
*/
static Locale getCountry(int code)
{
if (code == 0 || code == 9999) // not specified or other
return null;
String cryStr = countryIndexToLocaleString.get(code);
return (cryStr == null) ? null : new Locale("", cryStr);
}
/**
* Returns the index stored on the server corresponding the given locale
* @param cLocale Locale
* @return int
*/
static int getCountryCode(Locale cLocale)
{
if (cLocale == null)
return 0; // not specified
for (Map.Entry<Integer, String> entry : countryIndexToLocaleString.entrySet())
{
Integer key = entry.getKey();
String countryString = entry.getValue().toUpperCase();
if (countryString.equals(cLocale.getCountry()))
return key.intValue();
}
return 0; // not specified
}
/**
* Returns the Locale corresponding the index coming from icq server
* @param code int
* @return Locale
*/
static Locale getSpokenLanguage(int code)
{
if (code == 0 || code == 255) // not specified or other
return null;
return spokenLanguages[code];
}
/**
* Returns the index stored on the server corresponding the given locale
* @param locale Locale
* @return int
*/
static int getLanguageCode(Locale locale)
{
for (int i = 1; i < spokenLanguages.length; i++)
{
if (spokenLanguages[i].equals(locale))
return i;
}
return -1;
}
/**
* @param occupationStr String
* @return int
*/
static int getOccupationCode(String occupationStr)
{
for(int i = 0; i < occupations.length; i++)
{
if(occupations[i].equals(occupationStr))
return i;
}
return 0;
}
/**
* @param value String
* @return int
*/
static int getInterestCode(String value)
{
for (int i = 0; i < occupations.length; i++)
{
if (occupations[i].equals(value))
return i;
}
return 0;
}
/**
* Origin City of user
*/
public static class OriginCityDetail
extends ServerStoredDetails.CityDetail
{
public OriginCityDetail(String cityName)
{
super(cityName);
}
}
/**
* Origin Province of User
*/
public static class OriginProvinceDetail
extends ServerStoredDetails.ProvinceDetail
{
public OriginProvinceDetail(String workProvince)
{
super(workProvince);
}
}
/**
* Origin Postal Code of user
*/
public static class OriginPostalCodeDetail
extends ServerStoredDetails.PostalCodeDetail
{
public OriginPostalCodeDetail(String postalCode)
{
super(postalCode);
}
}
/**
* Fax at work
*/
public static class WorkFaxDetail
extends ServerStoredDetails.PhoneNumberDetail
{
public WorkFaxDetail(String number)
{
super(number);
super.detailDisplayName = "WorkFax";
}
}
/**
* Work department
*/
public static class WorkDepartmentNameDetail
extends ServerStoredDetails.NameDetail
{
public WorkDepartmentNameDetail(String workDepartmentName)
{
super("Work Department Name", workDepartmentName);
}
}
/**
* User position name at work
*/
public static class WorkPositionNameDetail
extends ServerStoredDetails.StringDetail
{
public WorkPositionNameDetail(String workPos)
{
super("Work Position", workPos);
}
}
/**
* User ocupation at work
*/
public static class WorkOcupationDetail
extends ServerStoredDetails.StringDetail
{
public WorkOcupationDetail(String value)
{
super("Work Ocupation", value);
}
}
/**
* User notes
*/
public static class NotesDetail
extends ServerStoredDetails.StringDetail
{
public NotesDetail(String value)
{
super("Notes", value);
}
}
/**
* User interests
*/
public static class InterestDetail
extends ServerStoredDetails.InterestDetail
{
private String category = null;
public InterestDetail(String value, String category)
{
super(value);
this.category = category;
}
public String getCategory()
{
return category;
}
}
/**
* Origin country Code of user
*/
public static class OriginCountryDetail
extends ServerStoredDetails.CountryDetail
{
public OriginCountryDetail(Locale locale)
{
super(locale);
}
}
// String corresponding to type indexes
static ServerStoredDetails.GenderDetail[] genders =
new ServerStoredDetails.GenderDetail[]
{
null,
ServerStoredDetails.GenderDetail.FEMALE,
ServerStoredDetails.GenderDetail.MALE
};
// this can be more simple
// just to init the strings in the sppec indexes
private static Locale spokenLanguages[] =
new Locale[]
{
null, // not specified
new Locale("ar"), // Arabic
new Locale("bh"), // LC_BHOJPURI Bhojpuri
new Locale("bg"), // LC_BULGARIAN Bulgarian
new Locale("my"), // LC_BURMESE Burmese
new Locale("zh", "hk"), // LC_CONTONESE Cantonese official in Hong Kong SAR and Macau SAR
new Locale("ca"), // LC_CATALAN Catalan
Locale.CHINA, // LC_CHINESE Chinese zh
new Locale("hr"), // LC_CROATIAN Croatian
new Locale("cs"), // LC_CZECH Czech
new Locale("da"), // LC_DANISH Danish
new Locale("nl"), // LC_DUTCH Dutch
new Locale("en"), // LC_ENGLISH English
new Locale("eo"), // LC_ESPERANTO Esperanto
new Locale("et"), // LC_ESTONIAN Estonian
new Locale("fa"), // LC_FARSI Farsi
new Locale("fi"), // LC_FINNISH Finnish
new Locale("fr"), // LC_FRENCH French
new Locale("gd"), // LC_GAELIC Gaelic
new Locale("de"), // LC_GERMAN German
new Locale("el"), // LC_GREEK Greek
new Locale("he"), // LC_HEBREW Hebrew
new Locale("hi"), // LC_HINDI Hindi
new Locale("hu"), // LC_HUNGARIAN Hungarian
new Locale("is"), // LC_ICELANDIC Icelandic
new Locale("id"), // LC_INDONESIAN Indonesian
new Locale("it"), // LC_ITALIAN Italian
new Locale("ja"), // LC_JAPANESE Japanese
new Locale("km"), // LC_KHMER Khmer
new Locale("ko"), // LC_KOREAN Korean
new Locale("lo"), // LC_LAO Lao
new Locale("lv"), // LC_LATVIAN Latvian
new Locale("lt"), // LC_LITHUANIAN Lithuanian
new Locale("ms"), // LC_MALAY Malay
new Locale("no"), // LC_NORWEGIAN Norwegian
new Locale("pl"), // LC_POLISH Polish
new Locale("pt"), // LC_PORTUGUESE Portuguese
new Locale("ro"), // LC_ROMANIAN Romanian
new Locale("ru"), // LC_RUSSIAN Russian
new Locale("sr"), // LC_SERBIAN Serbian
new Locale("sk"), // LC_SLOVAK Slovak
new Locale("sl"), // LC_SLOVENIAN Slovenian
new Locale("so"), // LC_SOMALI Somali
new Locale("es"), // LC_SPANISH Spanish
new Locale("sw"), // LC_SWAHILI Swahili
new Locale("sv"), // LC_SWEDISH Swedish
new Locale("tl"), // LC_TAGALOG Tagalog
new Locale("tt"), // LC_TATAR Tatar
new Locale("th"), // LC_THAI Thau
new Locale("tr"), // LC_TURKISH Turkish
new Locale("uk"), // LC_UKRAINIAN Ukarinian
new Locale("ur"), // LC_URDU Urdu
new Locale("vi"), // LC_VIETNAMESE Vietnamese
new Locale("yi"), // LC_YIDDISH Yiddish
new Locale("yo"), // LC_YORUBA Yoruba
new Locale("af"), // LC_AFRIKAANS Afriaans
new Locale("bs"), // LC_BOSNIAN Bosnian
new Locale("fa"), // LC_PERSIAN Persian
new Locale("sq"), // LC_ALBANIAN Albanian
new Locale("hy"), // LC_ARMENIAN Armenian
new Locale("pa"), // LC_PUNJABI Punjabi
new Locale("ch"), // LC_CHAMORRO Chamorro
new Locale("mn"), // LC_MONGOLIAN Mongolian
new Locale("zh"), // LC_MANDARIN Mandarin ???
Locale.TAIWAN, // LC_TAIWANESE Taiwanese ??? zh
new Locale("mk"), // LC_MACEDONIAN Macedonian
new Locale("sd"), // LC_SINDHI Sindhi
new Locale("cy"), // LC_WELSH Welsh
new Locale("az"), // LC_AZERBAIJANI Azerbaijani
new Locale("ku"), // LC_KURDISH Kurdish
new Locale("gu"), // LC_GUJARATI Gujarati
new Locale("ta"), // LC_TAMIL Tamil
new Locale("be"), // LC_BELORUSSIAN Belorussian
null // LC_OTHER 255 other
};
static String[] occupations = new String[]
{
"not specified",
"academic",
"administrative",
"art/entertainment",
"college student",
"computers",
"community & social",
"education",
"engineering",
"financial services",
"government",
"high school student",
"home",
"ICQ - providing help",
"law",
"managerial",
"manufacturing",
"medical/health",
"military",
"non-government organization",
"professional",
"retail",
"retired",
"science & research",
"sports",
"technical",
"university student",
"web building",
"other services"
};
static String[] interestsCategories = new String[]
{
"not specified",
"art",
"cars",
"celebrity fans",
"collections",
"computers",
"culture",
"fitness",
"games",
"hobbies",
"ICQ - help",
"internet",
"lifestyle",
"movies",
"music",
"outdoors",
"parenting",
"pets and animals",
"religion",
"science",
"skills",
"sports",
"web design",
"ecology",
"news and media",
"government",
"business",
"mystics",
"travel",
"astronomy",
"space",
"clothing",
"parties",
"women",
"social science",
"60's",
"70's",
"40's",
"50's",
"finance and corporate",
"entertainment",
"consumer electronics",
"retail stores",
"health and beauty",
"media",
"household products",
"mail order catalogue",
"business services",
"audio and visual",
"sporting and athletic",
"publishing",
"home automation"
};
// Hashtable holding the country index
// corresponding to the country locale string
private static final Map<Integer, String> countryIndexToLocaleString
= new Hashtable<Integer, String>();
static
{
// countryIndexToLocaleString.put((0),""); //not specified
countryIndexToLocaleString.put((1), "us"); //USA
countryIndexToLocaleString.put((101), "ai"); //Anguilla
countryIndexToLocaleString.put((102), "ag"); //Antigua
countryIndexToLocaleString.put((1021), "ag"); //Antigua & Barbuda
countryIndexToLocaleString.put((103), "bs"); //Bahamas
countryIndexToLocaleString.put((104), "bb"); //Barbados
countryIndexToLocaleString.put((105), "bm"); //Bermuda
countryIndexToLocaleString.put((106), "vg"); //British Virgin Islands
countryIndexToLocaleString.put((107), "ca"); //Canada
countryIndexToLocaleString.put((108), "ky"); //Cayman Islands
countryIndexToLocaleString.put((109), "dm"); //Dominica
countryIndexToLocaleString.put((110), "do"); //Dominican Republic
countryIndexToLocaleString.put((111), "gd"); //Grenada
countryIndexToLocaleString.put((112), "jm"); //Jamaica
countryIndexToLocaleString.put((113), "ms"); //Montserrat
countryIndexToLocaleString.put((114), "kn"); //Nevis
countryIndexToLocaleString.put((1141), "kn"); //Saint Kitts and Nevis
countryIndexToLocaleString.put((115), "kn"); //St. Kitts
countryIndexToLocaleString.put((116), "vc"); //St. Vincent & the Grenadines
countryIndexToLocaleString.put((117), "tt"); //Trinidad & Tobago
countryIndexToLocaleString.put((118), "tc"); //Turks & Caicos Islands
countryIndexToLocaleString.put((120), "ag"); //Barbuda
countryIndexToLocaleString.put((121), "pr"); //Puerto Rico
countryIndexToLocaleString.put((122), "lc"); //Saint Lucia
countryIndexToLocaleString.put((123), "vi"); //Virgin Islands (USA)
countryIndexToLocaleString.put((178), "es"); //Canary Islands ???
countryIndexToLocaleString.put((20), "eg"); //Egypt
countryIndexToLocaleString.put((212), "ma"); //Morocco
countryIndexToLocaleString.put((213), "dz"); //Algeria
countryIndexToLocaleString.put((216), "tn"); //Tunisia
countryIndexToLocaleString.put((218), "ly"); //Libyan Arab Jamahiriya
countryIndexToLocaleString.put((220), "gm"); //Gambia
countryIndexToLocaleString.put((221), "sn"); //Senegal
countryIndexToLocaleString.put((222), "mr"); //Mauritania
countryIndexToLocaleString.put((223), "ml"); //Mali
countryIndexToLocaleString.put((224), "pg"); //Guinea
countryIndexToLocaleString.put((225), "ci"); //Cote d'Ivoire
countryIndexToLocaleString.put((226), "bf"); //Burkina Faso
countryIndexToLocaleString.put((227), "ne"); //Niger
countryIndexToLocaleString.put((228), "tg"); //Togo
countryIndexToLocaleString.put((229), "bj"); //Benin
countryIndexToLocaleString.put((230), "mu"); //Mauritius
countryIndexToLocaleString.put((231), "lr"); //Liberia
countryIndexToLocaleString.put((232), "sl"); //Sierra Leone
countryIndexToLocaleString.put((233), "gh"); //Ghana
countryIndexToLocaleString.put((234), "ng"); //Nigeria
countryIndexToLocaleString.put((235), "td"); //Chad
countryIndexToLocaleString.put((236), "cf"); //Central African Republic
countryIndexToLocaleString.put((237), "cm"); //Cameroon
countryIndexToLocaleString.put((238), "cv"); //Cape Verde Islands
countryIndexToLocaleString.put((239), "st"); //Sao Tome & Principe
countryIndexToLocaleString.put((240), "gq"); //Equatorial Guinea
countryIndexToLocaleString.put((241), "ga"); //Gabon
countryIndexToLocaleString.put((242), "cg"); //Congo, (Rep. of the)
countryIndexToLocaleString.put((243), "cd"); //Congo, Democratic Republic of
countryIndexToLocaleString.put((244), "ao"); //Angola
countryIndexToLocaleString.put((245), "gw"); //Guinea-Bissau
// countryIndexToLocaleString.put((246),""); //Diego Garcia ???
// countryIndexToLocaleString.put((247),""); //Ascension Island ???
countryIndexToLocaleString.put((248), "sc"); //Seychelles
countryIndexToLocaleString.put((249), "sd"); //Sudan
countryIndexToLocaleString.put((250), "rw"); //Rwanda
countryIndexToLocaleString.put((251), "et"); //Ethiopia
countryIndexToLocaleString.put((252), "so"); //Somalia
countryIndexToLocaleString.put((253), "dj"); //Djibouti
countryIndexToLocaleString.put((254), "ke"); //Kenya
countryIndexToLocaleString.put((255), "tz"); //Tanzania
countryIndexToLocaleString.put((256), "ug"); //Uganda
countryIndexToLocaleString.put((257), "bi"); //Burundi
countryIndexToLocaleString.put((258), "mz"); //Mozambique
countryIndexToLocaleString.put((260), "zm"); //Zambia
countryIndexToLocaleString.put((261), "mg"); //Madagascar
// countryIndexToLocaleString.put((262),""); //Reunion Island ???
countryIndexToLocaleString.put((263), "zw"); //Zimbabwe
countryIndexToLocaleString.put((264), "na"); //Namibia
countryIndexToLocaleString.put((265), "mw"); //Malawi
countryIndexToLocaleString.put((266), "ls"); //Lesotho
countryIndexToLocaleString.put((267), "bw"); //Botswana
countryIndexToLocaleString.put((268), "sz"); //Swaziland
countryIndexToLocaleString.put((269), "yt"); //Mayotte Island
countryIndexToLocaleString.put((2691), "km"); //Comoros
countryIndexToLocaleString.put((27), "za"); //South Africa
countryIndexToLocaleString.put((290), "sh"); //St. Helena
countryIndexToLocaleString.put((291), "er"); //Eritrea
countryIndexToLocaleString.put((297), "aw"); //Aruba
// countryIndexToLocaleString.put((298),""); //Faeroe Islands ???
countryIndexToLocaleString.put((299), "gl"); //Greenland
countryIndexToLocaleString.put((30), "gr"); //Greece
countryIndexToLocaleString.put((31), "nl"); //Netherlands
countryIndexToLocaleString.put((32), "be"); //Belgium
countryIndexToLocaleString.put((33), "fr"); //France
countryIndexToLocaleString.put((34), "es"); //Spain
countryIndexToLocaleString.put((350), "gi"); //Gibraltar
countryIndexToLocaleString.put((351), "pt"); //Portugal
countryIndexToLocaleString.put((352), "lu"); //Luxembourg
countryIndexToLocaleString.put((353), "ie"); //Ireland
countryIndexToLocaleString.put((354), "is"); //Iceland
countryIndexToLocaleString.put((355), "al"); //Albania
countryIndexToLocaleString.put((356), "mt"); //Malta
countryIndexToLocaleString.put((357), "cy"); //Cyprus
countryIndexToLocaleString.put((358), "fi"); //Finland
countryIndexToLocaleString.put((359), "bg"); //Bulgaria
countryIndexToLocaleString.put((36), "hu"); //Hungary
countryIndexToLocaleString.put((370), "lt"); //Lithuania
countryIndexToLocaleString.put((371), "lv"); //Latvia
countryIndexToLocaleString.put((372), "ee"); //Estonia
countryIndexToLocaleString.put((373), "md"); //Moldova, Republic of
countryIndexToLocaleString.put((374), "am"); //Armenia
countryIndexToLocaleString.put((375), "by"); //Belarus
countryIndexToLocaleString.put((376), "ad"); //Andorra
countryIndexToLocaleString.put((377), "mc"); //Monaco
countryIndexToLocaleString.put((378), "sm"); //San Marino
countryIndexToLocaleString.put((379), "va"); //Vatican City
countryIndexToLocaleString.put((380), "ua"); //Ukraine
// countryIndexToLocaleString.put((381),""); //Yugoslavia ???
countryIndexToLocaleString.put((3811), "cs"); //Yugoslavia - Serbia
countryIndexToLocaleString.put((382), "cs"); //Yugoslavia - Montenegro
countryIndexToLocaleString.put((385), "hr"); //Croatia
countryIndexToLocaleString.put((386), "si"); //Slovenia
countryIndexToLocaleString.put((387), "ba"); //Bosnia & Herzegovina
countryIndexToLocaleString.put((389), "mk"); //Macedonia (F.Y.R.O.M.)
countryIndexToLocaleString.put((39), "it"); //Italy
countryIndexToLocaleString.put((40), "ro"); //Romania
countryIndexToLocaleString.put((41), "ch"); //Switzerland
countryIndexToLocaleString.put((4101), "li"); //Liechtenstein
countryIndexToLocaleString.put((42), "cz"); //Czech Republic
countryIndexToLocaleString.put((4201), "sk"); //Slovakia
countryIndexToLocaleString.put((43), "at"); //Austria
countryIndexToLocaleString.put((44), "gb"); //United Kingdom
// countryIndexToLocaleString.put((441),""); //Wales ???
// countryIndexToLocaleString.put((442),""); //Scotland ???
countryIndexToLocaleString.put((45), "dk"); //Denmark
countryIndexToLocaleString.put((46), "se"); //Sweden
countryIndexToLocaleString.put((47), "no"); //Norway
countryIndexToLocaleString.put((48), "pl"); //Poland
countryIndexToLocaleString.put((49), "de"); //Germany
// countryIndexToLocaleString.put((500),""); //Falkland Islands ???
countryIndexToLocaleString.put((501), "bz"); //Belize
countryIndexToLocaleString.put((502), "gt"); //Guatemala
countryIndexToLocaleString.put((503), "sv"); //El Salvador
countryIndexToLocaleString.put((504), "hn"); //Honduras
countryIndexToLocaleString.put((505), "ni"); //Nicaragua
countryIndexToLocaleString.put((506), "cr"); //Costa Rica
countryIndexToLocaleString.put((507), "pa"); //Panama
countryIndexToLocaleString.put((508), "pm"); //St. Pierre & Miquelon
countryIndexToLocaleString.put((509), "ht"); //Haiti
countryIndexToLocaleString.put((51), "pe"); //Peru
countryIndexToLocaleString.put((52), "mx"); //Mexico
countryIndexToLocaleString.put((53), "cu"); //Cuba
countryIndexToLocaleString.put((54), "ar"); //Argentina
countryIndexToLocaleString.put((55), "br"); //Brazil
countryIndexToLocaleString.put((56), "cl"); //Chile, Republic of
countryIndexToLocaleString.put((57), "co"); //Colombia
countryIndexToLocaleString.put((58), "ve"); //Venezuela
countryIndexToLocaleString.put((590), "gp"); //Guadeloupe
countryIndexToLocaleString.put((5901), "an"); //French Antilles
countryIndexToLocaleString.put((5902), "an"); //Antilles
countryIndexToLocaleString.put((591), "bo"); //Bolivia
countryIndexToLocaleString.put((592), "gy"); //Guyana
countryIndexToLocaleString.put((593), "ec"); //Ecuador
countryIndexToLocaleString.put((594), "gy"); //French Guyana
countryIndexToLocaleString.put((595), "py"); //Paraguay
countryIndexToLocaleString.put((596), "mq"); //Martinique
countryIndexToLocaleString.put((597), "sr"); //Suriname
countryIndexToLocaleString.put((598), "uy"); //Uruguay
countryIndexToLocaleString.put((599), "an"); //Netherlands Antilles
countryIndexToLocaleString.put((60), "my"); //Malaysia
countryIndexToLocaleString.put((61), "au"); //Australia
countryIndexToLocaleString.put((6101), "cc"); //Cocos-Keeling Islands
countryIndexToLocaleString.put((6102), "cc"); //Cocos (Keeling) Islands
countryIndexToLocaleString.put((62), "id"); //Indonesia
countryIndexToLocaleString.put((63), "ph"); //Philippines
countryIndexToLocaleString.put((64), "nz"); //New Zealand
countryIndexToLocaleString.put((65), "sg"); //Singapore
countryIndexToLocaleString.put((66), "th"); //Thailand
// countryIndexToLocaleString.put((670),""); //Saipan Island ???
// countryIndexToLocaleString.put((6701),""); //Rota Island ???
// countryIndexToLocaleString.put((6702),""); //Tinian Island ???
countryIndexToLocaleString.put((671), "gu"); //Guam, US Territory of
countryIndexToLocaleString.put((672), "cx"); //Christmas Island
countryIndexToLocaleString.put((6722), "nf"); //Norfolk Island
countryIndexToLocaleString.put((673), "bn"); //Brunei
countryIndexToLocaleString.put((674), "nr"); //Nauru
countryIndexToLocaleString.put((675), "pg"); //Papua New Guinea
countryIndexToLocaleString.put((676), "to"); //Tonga
countryIndexToLocaleString.put((677), "sb"); //Solomon Islands
countryIndexToLocaleString.put((678), "vu"); //Vanuatu
countryIndexToLocaleString.put((679), "fj"); //Fiji
countryIndexToLocaleString.put((680), "pw"); //Palau
countryIndexToLocaleString.put((681), "wf"); //Wallis & Futuna Islands
countryIndexToLocaleString.put((682), "ck"); //Cook Islands
countryIndexToLocaleString.put((683), "nu"); //Niue
countryIndexToLocaleString.put((684), "as"); //American Samoa
countryIndexToLocaleString.put((685), "ws"); //Western Samoa
countryIndexToLocaleString.put((686), "ki"); //Kiribati
countryIndexToLocaleString.put((687), "nc"); //New Caledonia
countryIndexToLocaleString.put((688), "tv"); //Tuvalu
countryIndexToLocaleString.put((689), "pf"); //French Polynesia
countryIndexToLocaleString.put((690), "tk"); //Tokelau
countryIndexToLocaleString.put((691), "fm"); //Micronesia, Federated States of
countryIndexToLocaleString.put((692), "mh"); //Marshall Islands
countryIndexToLocaleString.put((7), "ru"); //Russia
countryIndexToLocaleString.put((705), "kz"); //Kazakhstan
countryIndexToLocaleString.put((706), "kg"); //Kyrgyzstan
countryIndexToLocaleString.put((708), "tj"); //Tajikistan
countryIndexToLocaleString.put((709), "tm"); //Turkmenistan
countryIndexToLocaleString.put((711), "uz"); //Uzbekistan
countryIndexToLocaleString.put((81), "jp"); //Japan
countryIndexToLocaleString.put((82), "kr"); //Korea, South
countryIndexToLocaleString.put((84), "vn"); //Viet Nam
countryIndexToLocaleString.put((850), "kp"); //Korea, North
countryIndexToLocaleString.put((852), "hk"); //Hong Kong
countryIndexToLocaleString.put((853), "mo"); //Macau
countryIndexToLocaleString.put((855), "kh"); //Cambodia
countryIndexToLocaleString.put((856), "la"); //Laos
countryIndexToLocaleString.put((86), "cn"); //China
countryIndexToLocaleString.put((880), "bd"); //Bangladesh
countryIndexToLocaleString.put((886), "tw"); //Taiwan
countryIndexToLocaleString.put((90), "tr"); //Turkey
countryIndexToLocaleString.put((91), "in"); //India
countryIndexToLocaleString.put((92), "pk"); //Pakistan
countryIndexToLocaleString.put((93), "af"); //Afghanistan
countryIndexToLocaleString.put((94), "lk"); //Sri Lanka
countryIndexToLocaleString.put((95), "mm"); //Myanmar
countryIndexToLocaleString.put((960), "mv"); //Maldives
countryIndexToLocaleString.put((961), "lb"); //Lebanon
countryIndexToLocaleString.put((962), "jo"); //Jordan
countryIndexToLocaleString.put((963), "sy"); //Syrian Arab Republic
countryIndexToLocaleString.put((964), "iq"); //Iraq
countryIndexToLocaleString.put((965), "kw"); //Kuwait
countryIndexToLocaleString.put((966), "sa"); //Saudi Arabia
countryIndexToLocaleString.put((967), "ye"); //Yemen
countryIndexToLocaleString.put((968), "om"); //Oman
countryIndexToLocaleString.put((971), "ae"); //United Arabian Emirates
countryIndexToLocaleString.put((972), "il"); //Israel
countryIndexToLocaleString.put((973), "bh"); //Bahrain
countryIndexToLocaleString.put((974), "qa"); //Qatar
countryIndexToLocaleString.put((975), "bt"); //Bhutan
countryIndexToLocaleString.put((976), "mn"); //Mongolia
countryIndexToLocaleString.put((977), "np"); //Nepal
countryIndexToLocaleString.put((98), "ir"); //Iran (Islamic Republic of)
countryIndexToLocaleString.put((994), "az"); //Azerbaijan
countryIndexToLocaleString.put((995), "ge"); //Georgia
// countryIndexToLocaleString.put((9999),""); //other
}
/**
* Notified if buddy icon is changed
*/
private class IconUpdateListener
implements IconRequestListener
{
public void buddyIconCleared(IconService iconService,
Screenname screenname,
ExtraInfoData extraInfoData)
{}
public void buddyIconUpdated(IconService iconService,
Screenname screenname,
ExtraInfoData extraInfoData,
ByteBlock byteBlock)
{
if(byteBlock != null)
{
if(screenname.getFormatted().equals(uin))
{
synchronized(this)
{
byte[] img = byteBlock.toByteArray();
if(img != null && img.length > 0)
accountImage = new ImageDetail("Account Image", img);
this.notifyAll();
}
}
}
}
public void waitForImage(long waitFor)
{
synchronized(this)
{
try{
if(accountImage == null)
wait(waitFor);
}
catch (InterruptedException ex)
{
if (logger.isDebugEnabled())
logger.debug(
"Interrupted while waiting for a subscription evt", ex);
}
}
}
}
/**
*
*/
// private class ChangeDetailInfoCmd extends ToIcqCmd
// {
// // used when semding this command for changeg details stored on the server
// private String senderUin = null;
// private List changeDataTlvs = new LinkedList();
//
// /**
// * Constructs command send to server
// * @param senderUin String the uin of the sender
// * @param changedData List the data to be changed
// * @param toBeCleared List the data to be cleared,
// * if no such data null can be passed
// */
// public ChangeDetailInfoCmd(String senderUin, List changedData,
// List toBeCleared)
// {
// super(Long.parseLong(senderUin), CMD_SET_FULLINFO, 2);
// this.senderUin = senderUin;
//
// // if toBeCleared == null. make it empty one
// if (toBeCleared == null)
// toBeCleared = new ArrayList();
//
// // fix the spoken languages must be 3
// int lastSpokenIndex = -1;
// int countOfLanguages = 0;
// boolean isLanguageFound = false;
// for (int i = 0; i < changedData.size(); i++)
// {
// Object item = changedData.get(i);
// if (item instanceof ServerStoredDetails.SpokenLanguageDetail)
// {
// isLanguageFound = true;
// lastSpokenIndex = i;
// countOfLanguages++;
// }
// }
//
// if (isLanguageFound)
// {
// for (int i = countOfLanguages; i < 3; i++)
// {
// lastSpokenIndex++;
// changedData.add(lastSpokenIndex,
// new ServerStoredDetails.SpokenLanguageDetail(null));
// }
// }
//
// Iterator iter = changedData.iterator();
// while (iter.hasNext())
// {
// ServerStoredDetails.GenericDetail item =
// (ServerStoredDetails.GenericDetail) iter.next();
//
// if (toBeCleared.contains(item))
// changeDataTlvs.add(getClearTlv(item));
// else
// changeDataTlvs.add(getTlvForChange(item));
// }
// }
//
// public void writeIcqData(OutputStream out)
// throws IOException
// {
// // write tlvs with data here
// Iterator iter = changeDataTlvs.iterator();
// while (iter.hasNext())
// {
// DetailTlv item = (DetailTlv) iter.next();
// item.write(out);
// }
//
// }
//
// /**
// * Correspondig the type of ServerStoredDetails returns empty Tlv or Tlv
// * with default value
// * @param detail GenericDetail
// * @return DetailTlv
// */
// private DetailTlv getClearTlv(ServerStoredDetails.GenericDetail detail)
// {
// int typeOfDetail = supportedTypes.get(detail.getClass())[1];
//
// DetailTlv result = new DetailTlv(supportedTypes.get(detail.getClass())[1]);
//
// switch (typeOfDetail)
// {
// case 0x01A4: //CountryDetail
// case 0x0334: //OriginCountryDetail
// case 0x02B2: //WorkCountryDetail
// result.writeUShort(0);
// break;
//
// case 0x0186: //SpokenLanguageDetail
// logger.trace("write lang 0");
// result.writeUShort(0);
// case 0x017C: //GenderDetail
// result.writeUByte(0);
// case 0x023A: //BirthDateDetail
// result.writeUShort(0);
// result.writeUShort(0);
// result.writeUShort(0);
// case 0x01CC: //WorkOcupationDetail
// result.writeUShort(0);
// case 0x01EA: //InterestDetail
// result.writeUShort(0);
// result.writeString("");
// case 0x0316:
// result.writeUByte(0);
// default:
// result.writeString("");
// }
//
// return result;
// }
//
// /**
// * Converts ServerStoredDetails to Tlv which later is converted to bytes
// * and send to server
// * @param detail GenericDetail the detail
// * @return DetailTlv
// */
// private DetailTlv getTlvForChange(ServerStoredDetails.GenericDetail detail)
// {
// int typeOfDetail = supportedTypes.get(detail.getClass())[1];
//
// DetailTlv result = new DetailTlv(typeOfDetail);
//
// switch (typeOfDetail)
// {
// case 0x01A4: //CountryDetail
// case 0x0334: //OriginCountryDetail
// case 0x02B2: //WorkCountryDetail
// result.writeUShort(getCountryCode( ( (ServerStoredDetails.
// LocaleDetail) detail).getLocale()));
// break;
//
// case 0x0186: //SpokenLanguageDetail
// writeLanguageCode( (ServerStoredDetails.LocaleDetail) detail,
// result);
// break;
// case 0x017C: //GenderDetail
// writeGenderCode( (ServerStoredDetails.GenderDetail) detail,
// result);
// break;
// case 0x023A: //BirthDateDetail
// writeCalendarCode( (ServerStoredDetails.CalendarDetail) detail,
// result);
// break;
// case 0x01CC: //WorkOcupationDetail
// writeOccupationCode( (WorkOcupationDetail) detail, result);
// break;
// case 0x01EA: //InterestDetail
// writeInterestCode( (InterestDetail) detail, result);
// break;
// default:
// writeGenericDetail(detail, result);
// }
//
// return result;
// }
//
// /**
// * Writes the corresponding index for Language from ServerStoredDetails to the tlv
// * @param detail LocaleDetail
// * @param tlv DetailTlv
// */
// private void writeLanguageCode(ServerStoredDetails.LocaleDetail detail,
// DetailTlv tlv)
// {
// Locale newLang = detail.getLocale();
// if (newLang == null)
// {
// // this indicates that we must set language as not specified
// tlv.writeUShort(0);
// logger.trace("write lang 0");
// }
// else
// {
// for (int i = 1; i < spokenLanguages.length; i++)
// {
// // indicating that language is not set
// if (getSpokenLanguage(i).equals(newLang))
// {
// logger.trace("write lang " + i);
// tlv.writeUShort(i);
// return;
// }
// }
// }
// }
//
// /**
// * Writes the corresponding index for Gender from ServerStoredDetails to the tlv
// * @param detail GenderDetail
// * @param tlv DetailTlv
// */
// private void writeGenderCode(ServerStoredDetails.GenderDetail detail,
// DetailTlv tlv)
// {
// int gender = 0;
//
// if (detail.equals(ServerStoredDetails.GenderDetail.FEMALE))
// gender = 1;
// else if (detail.equals(ServerStoredDetails.GenderDetail.MALE))
// gender = 2;
//
// tlv.writeUByte(gender);
// }
//
// /**
// * Writes the corresponding index for Calendar(BirthDate) from ServerStoredDetails to the tlv
// * @param detail CalendarDetail
// * @param tlv DetailTlv
// */
// private void writeCalendarCode(ServerStoredDetails.CalendarDetail detail,
// DetailTlv tlv)
// {
// Calendar calendar = detail.getCalendar();
//
// tlv.writeUShort(calendar.get(Calendar.YEAR));
// tlv.writeUShort(calendar.get(Calendar.MONTH));
// tlv.writeUShort(calendar.get(Calendar.DAY_OF_MONTH));
// }
//
// /**
// * Writes the corresponding index for Occupation from ServerStoredDetails to the tlv
// * @param detail WorkOcupationDetail
// * @param tlv DetailTlv
// */
// private void writeOccupationCode(WorkOcupationDetail detail, DetailTlv tlv)
// {
// for (int i = 0; i < occupations.length; i++)
// {
// if (occupations[i].equals(detail.getDetailValue()))
// tlv.writeUShort(i);
// }
// }
//
// /**
// * Writes the corresponding index for Interests from ServerStoredDetails to the tlv
// * @param detail InterestDetail
// * @param tlv DetailTlv
// */
// private void writeInterestCode(InterestDetail detail, DetailTlv tlv)
// {
// String category = detail.getCategory();
// int categoryInt = 0;
// for (int i = 0; i < interestsCategories.length; i++)
// {
// if (interestsCategories[i].equals(category))
// {
// if (i != 0)
// categoryInt = i + 99;
// else
// categoryInt = 0;
//
// break;
// }
// }
//
// tlv.writeUShort(categoryInt);
// tlv.writeString(detail.getInterest());
// }
//
// /**
// * Writes the corresponding value for ServerStoredDetails to the tlv
// * @param detail GenericDetail
// * @param tlv DetailTlv
// */
// private void writeGenericDetail(ServerStoredDetails.GenericDetail detail,
// DetailTlv tlv)
// {
// if (detail instanceof ServerStoredDetails.StringDetail)
// {
// tlv.writeString( ( (ServerStoredDetails.StringDetail) detail).
// getString());
// }
// else
// if (detail instanceof ServerStoredDetails.TimeZoneDetail)
// {
// int offset = ( (ServerStoredDetails.TimeZoneDetail) detail).
// getTimeZone().getRawOffset() / (60 * 60 * 1000);
// tlv.writeUByte(offset);
// }
// }
//
// }
//
// /**
// * Tlv set in command for changis user account info stored on server
// * @author Damian Minkov
// */
// public class DetailTlv
// implements Writable
// {
// private byte[] data = new byte[0];
// private int type;
//
// public DetailTlv(int type)
// {
// this.type = type;
// }
//
// public void write(OutputStream out) throws IOException
// {
// LEBinaryTools.writeUShort(out, type);
// LEBinaryTools.writeUShort(out, data.length);
// out.write(data);
// }
//
// public long getWritableLength()
// {
// return 4 + data.length;
// }
//
// public void writeUInt(long number)
// {
// byte[] tmp = LEBinaryTools.getUInt(number);
// byte[] newData = new byte[data.length + tmp.length];
//
// System.arraycopy(data, 0, newData, 0, data.length);
// System.arraycopy(tmp, 0, newData, data.length, tmp.length);
//
// data = newData;
// }
//
// public void writeUShort(int number)
// {
// byte[] tmp = LEBinaryTools.getUShort(number);
// byte[] newData = new byte[data.length + tmp.length];
//
// System.arraycopy(data, 0, newData, 0, data.length);
// System.arraycopy(tmp, 0, newData, data.length, tmp.length);
//
// data = newData;
// }
//
// public void writeUByte(int number)
// {
// byte[] tmp = LEBinaryTools.getUByte(number);
// byte[] newData = new byte[data.length + tmp.length];
//
// System.arraycopy(data, 0, newData, 0, data.length);
// System.arraycopy(tmp, 0, newData, data.length, tmp.length);
//
// data = newData;
// }
//
// public void writeString(String str)
// {
// if (str == null)
// str = ""; // empty string so length will be 0 and nothing to be writen
//
// byte[] tmp = BinaryTools.getAsciiBytes(str);
//
// // save the string length before we process the string bytes
// writeUShort(tmp.length);
//
// byte[] newData = new byte[data.length + tmp.length];
//
// System.arraycopy(data, 0, newData, 0, data.length);
// System.arraycopy(tmp, 0, newData, data.length, tmp.length);
//
// data = newData;
// }
//
// public String toString()
// {
// StringBuffer result = new StringBuffer();
// ByteArrayOutputStream out = new ByteArrayOutputStream();
//
// try
// {
// write(out);
// }
// catch (IOException ex)
// {
// ex.printStackTrace();
// return null;
// }
//
// byte[] arrOut = out.toByteArray();
// for (int i = 0; i < arrOut.length; i++)
// {
// byte temp = arrOut[i];
// result.append(Integer.toHexString(temp & 0xFF)).append(' ');
// }
//
// return result.toString();
// }
// }
//
}