Karl
Karl

Reputation: 1244

Google Admin SDK: Directory Users: How to get User phone numbers using Java client?

I successfully authenticate using a Service Account and can list the users in my company's Google Directory.

However I want to list Users' telephone numbers.

I used the java quickstart example code and it works. However it is only printing the User's primary email address.

I wanted to use the User.getPhones() method to get the list/array of phone numbers for each user but the Java API returns "Object" see the Google java API

I know that the real result of the Google request is JSON and a User has an Array of Phones which have a "type" and a "value" eg work: num (Admin SDK User Representation)

I know that the google Java client is using a Google specific Jackson2 implementation,

com.google.api.client.json.jackson2.JacksonFactory

How can I influence it to produce UserPhone objects and not just java.lang.Object?

Cheers Karl

Upvotes: 3

Views: 1611

Answers (1)

jankeir
jankeir

Reputation: 350

I have come up with the following method that translate the generic List of ArrayMaps of <String,Object> objects in the Admin SDK. It requires the following imports:

import com.google.api.client.json.GenericJson;
import com.google.api.client.util.ArrayMap;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Here's the method that does the parsing:

public <T extends GenericJson> List<T> parse(Object genericItem, Class<T> clazz){
     List<T> result = new ArrayList<T>();
     if (genericItem != null){
         try {
             Constructor<T> constructor = clazz.getConstructor(new Class[0]);    // find the default constructor of the input class type
             List<ArrayMap<String,Object>> objects = (List<ArrayMap<String,Object>>)genericItem;
             for (ArrayMap<String,Object> object: objects){
                T id = constructor.newInstance(); // call the default constructor
                for (int i = 0; i < object.size(); i++)
                    id.put(object.getKey(i), object.getValue(i));
                result.add(id);
            }
        } catch (NoSuchMethodException ex) {
               Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ListArrayMapParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return result;
}

This works like this:

List<UserPhone> phones = parser.parse(user.getPhones(), UserPhone.class);
List<UserExternalId> externalIds = parser.parse(user.getExternalIds(),    UserExternalId.class);
List<UserOrganization> organizations = parser.parse(user.getOrganizations(), UserOrganization.class);
List<UserEmail> userEmails = parser.parse(user.getEmails(), UserEmail.class); 

Once you've done this you can update the phones, externalIds,... and then do user.setPhones(phones) and the User object will handle the new objects fine when saving.

I don't think you can have the API return the parsed result automatically for you today.

Upvotes: 6

Related Questions