Example usage for java.util Locale toString

List of usage examples for java.util Locale toString

Introduction

In this page you can find the example usage for java.util Locale toString.

Prototype

@Override
public final String toString() 

Source Link

Document

Returns a string representation of this Locale object, consisting of language, country, variant, script, and extensions as below:
language + "_" + country + "_" + (variant + "_#" | "#") + script + "_" + extensions
Language is always lower case, country is always upper case, script is always title case, and extensions are always lower case.

Usage

From source file:com.gst.infrastructure.core.serialization.JsonParserHelper.java

public Integer convertToInteger(final String numericalValueFormatted, final String parameterName,
        final Locale clientApplicationLocale) {

    if (clientApplicationLocale == null) {

        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final String defaultMessage = new StringBuilder(
                "The parameter '" + parameterName + "' requires a 'locale' parameter to be passed with it.")
                        .toString();/*from ww w . j  a v a  2  s .c  o  m*/
        final ApiParameterError error = ApiParameterError
                .parameterError("validation.msg.missing.locale.parameter", defaultMessage, parameterName);
        dataValidationErrors.add(error);

        throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                "Validation errors exist.", dataValidationErrors);
    }

    try {
        Integer number = null;

        if (StringUtils.isNotBlank(numericalValueFormatted)) {

            String source = numericalValueFormatted.trim();

            final NumberFormat format = NumberFormat.getInstance(clientApplicationLocale);
            final DecimalFormat df = (DecimalFormat) format;
            final DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
            df.setParseBigDecimal(true);

            // http://bugs.sun.com/view_bug.do?bug_id=4510618
            final char groupingSeparator = symbols.getGroupingSeparator();
            if (groupingSeparator == '\u00a0') {
                source = source.replaceAll(" ", Character.toString('\u00a0'));
            }

            final Number parsedNumber = df.parse(source);

            final double parsedNumberDouble = parsedNumber.doubleValue();
            final int parsedNumberInteger = parsedNumber.intValue();

            if (source.contains(Character.toString(symbols.getDecimalSeparator()))) {
                throw new ParseException(source, 0);
            }

            if (!Double.valueOf(parsedNumberDouble)
                    .equals(Double.valueOf(Integer.valueOf(parsedNumberInteger)))) {
                throw new ParseException(source, 0);
            }

            number = parsedNumber.intValue();
        }

        return number;
    } catch (final ParseException e) {

        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final ApiParameterError error = ApiParameterError.parameterError(
                "validation.msg.invalid.integer.format",
                "The parameter " + parameterName + " has value: " + numericalValueFormatted
                        + " which is invalid integer value for provided locale of ["
                        + clientApplicationLocale.toString() + "].",
                parameterName, numericalValueFormatted, clientApplicationLocale);
        error.setValue(numericalValueFormatted);
        dataValidationErrors.add(error);

        throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                "Validation errors exist.", dataValidationErrors);
    }
}

From source file:org.alfresco.repo.search.impl.solr.SolrQueryHTTPClient.java

public ResultSet executeQuery(final SearchParameters searchParameters, String language) {
    if (repositoryState.isBootstrapping()) {
        throw new AlfrescoRuntimeException(
                "SOLR queries can not be executed while the repository is bootstrapping");
    }// w  w w .jav  a 2 s.  c o m

    try {
        StoreRef store = extractStoreRef(searchParameters);
        SolrStoreMappingWrapper mapping = extractMapping(store);
        Locale locale = extractLocale(searchParameters);

        URLCodec encoder = new URLCodec();
        StringBuilder url = new StringBuilder();

        Pair<HttpClient, String> httpClientAndBaseUrl = mapping.getHttpClientAndBaseUrl();
        HttpClient httpClient = httpClientAndBaseUrl.getFirst();

        url.append(httpClientAndBaseUrl.getSecond());

        String languageUrlFragment = extractLanguageFragment(language);
        if (!url.toString().endsWith("/")) {
            url.append("/");
        }
        url.append(languageUrlFragment);

        // Send the query in JSON only
        // url.append("?q=");
        // url.append(encoder.encode(searchParameters.getQuery(), "UTF-8"));
        url.append("?wt=").append(encoder.encode("json", "UTF-8"));
        url.append("&fl=").append(encoder.encode("DBID,score", "UTF-8"));

        if ((searchParameters.getStores().size() > 1) || (mapping.isSharded())) {
            boolean requiresSeparator = false;
            url.append("&shards=");
            for (StoreRef storeRef : searchParameters.getStores()) {
                SolrStoreMappingWrapper storeMapping = extractMapping(storeRef);

                if (requiresSeparator) {
                    url.append(',');
                } else {
                    requiresSeparator = true;
                }

                url.append(storeMapping.getShards());

            }
        }

        // Emulate old limiting behaviour and metadata
        final LimitBy limitBy;
        int maxResults = -1;
        if (searchParameters.getMaxItems() >= 0) {
            maxResults = searchParameters.getMaxItems();
            limitBy = LimitBy.FINAL_SIZE;
        } else if (searchParameters.getLimitBy() == LimitBy.FINAL_SIZE && searchParameters.getLimit() >= 0) {
            maxResults = searchParameters.getLimit();
            limitBy = LimitBy.FINAL_SIZE;
        } else {
            maxResults = searchParameters.getMaxPermissionChecks();
            if (maxResults < 0) {
                maxResults = maximumResultsFromUnlimitedQuery;
            }
            limitBy = LimitBy.NUMBER_OF_PERMISSION_EVALUATIONS;
        }
        url.append("&rows=").append(String.valueOf(maxResults));

        url.append("&df=").append(encoder.encode(searchParameters.getDefaultFieldName(), "UTF-8"));
        url.append("&start=").append(encoder.encode("" + searchParameters.getSkipCount(), "UTF-8"));

        url.append("&locale=");
        url.append(encoder.encode(locale.toString(), "UTF-8"));
        url.append("&").append(SearchParameters.ALTERNATIVE_DICTIONARY).append("=")
                .append(alternativeDictionary);
        for (String paramName : searchParameters.getExtraParameters().keySet()) {
            url.append("&").append(paramName).append("=")
                    .append(searchParameters.getExtraParameters().get(paramName));
        }
        StringBuffer sortBuffer = buildSortParameters(searchParameters, encoder);
        url.append(sortBuffer);

        if (searchParameters.getPermissionEvaluation() != PermissionEvaluationMode.NONE) {
            url.append("&fq=").append(encoder.encode("{!afts}AUTHORITY_FILTER_FROM_JSON", "UTF-8"));
        }

        if (searchParameters.getExcludeTenantFilter() == false) {
            url.append("&fq=").append(encoder.encode("{!afts}TENANT_FILTER_FROM_JSON", "UTF-8"));
        }

        if (searchParameters.getFieldFacets().size() > 0 || searchParameters.getFacetQueries().size() > 0) {
            url.append("&facet=").append(encoder.encode("true", "UTF-8"));
            for (FieldFacet facet : searchParameters.getFieldFacets()) {
                url.append("&facet.field=").append(encoder.encode(facet.getField(), "UTF-8"));
                if (facet.getEnumMethodCacheMinDF() != 0) {
                    url.append("&")
                            .append(encoder.encode("f." + facet.getField() + ".facet.enum.cache.minDf",
                                    "UTF-8"))
                            .append("=").append(encoder.encode("" + facet.getEnumMethodCacheMinDF(), "UTF-8"));
                }
                int facetLimit;
                if (facet.getLimitOrNull() == null) {
                    if (mapping.isSharded()) {
                        facetLimit = defaultShardedFacetLimit;
                    } else {
                        facetLimit = defaultUnshardedFacetLimit;
                    }
                } else {
                    facetLimit = facet.getLimitOrNull().intValue();
                }
                url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.limit", "UTF-8"))
                        .append("=").append(encoder.encode("" + facetLimit, "UTF-8"));
                if (facet.getMethod() != null) {
                    url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.method", "UTF-8"))
                            .append("=").append(encoder.encode(
                                    facet.getMethod() == FieldFacetMethod.ENUM ? "enum" : "fc", "UTF-8"));
                }
                if (facet.getMinCount() != 0) {
                    url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.mincount", "UTF-8"))
                            .append("=").append(encoder.encode("" + facet.getMinCount(), "UTF-8"));
                }
                if (facet.getOffset() != 0) {
                    url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.offset", "UTF-8"))
                            .append("=").append(encoder.encode("" + facet.getOffset(), "UTF-8"));
                }
                if (facet.getPrefix() != null) {
                    url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.prefix", "UTF-8"))
                            .append("=").append(encoder.encode("" + facet.getPrefix(), "UTF-8"));
                }
                if (facet.getSort() != null) {
                    url.append("&").append(encoder.encode("f." + facet.getField() + ".facet.sort", "UTF-8"))
                            .append("=").append(encoder.encode(
                                    facet.getSort() == FieldFacetSort.COUNT ? "count" : "index", "UTF-8"));
                }

            }
            for (String facetQuery : searchParameters.getFacetQueries()) {
                if (!facetQuery.startsWith("{!afts")) {
                    facetQuery = "{!afts}" + facetQuery;
                }
                url.append("&facet.query=").append(encoder.encode(facetQuery, "UTF-8"));
            }
        }

        // filter queries
        for (String filterQuery : searchParameters.getFilterQueries()) {
            if (!filterQuery.startsWith("{!afts")) {
                filterQuery = "{!afts}" + filterQuery;
            }
            url.append("&fq=").append(encoder.encode(filterQuery, "UTF-8"));
        }

        // end of field facets

        final String searchTerm = searchParameters.getSearchTerm();
        String spellCheckQueryStr = null;
        if (searchTerm != null && searchParameters.isSpellCheck()) {
            StringBuilder builder = new StringBuilder();
            builder.append("&spellcheck.q=").append(encoder.encode(searchTerm, "UTF-8"));
            builder.append("&spellcheck=").append(encoder.encode("true", "UTF-8"));
            spellCheckQueryStr = builder.toString();
            url.append(spellCheckQueryStr);
        }

        JSONObject body = new JSONObject();
        body.put("query", searchParameters.getQuery());

        // Authorities go over as is - and tenant mangling and query building takes place on the SOLR side

        Set<String> allAuthorisations = permissionService.getAuthorisations();
        boolean includeGroups = includeGroupsForRoleAdmin ? true
                : !allAuthorisations.contains(PermissionService.ADMINISTRATOR_AUTHORITY);

        JSONArray authorities = new JSONArray();
        for (String authority : allAuthorisations) {
            if (includeGroups) {
                authorities.put(authority);
            } else {
                if (AuthorityType.getAuthorityType(authority) != AuthorityType.GROUP) {
                    authorities.put(authority);
                }
            }
        }
        body.put("authorities", authorities);
        body.put("anyDenyDenies", anyDenyDenies);

        JSONArray tenants = new JSONArray();
        tenants.put(tenantService.getCurrentUserDomain());
        body.put("tenants", tenants);

        JSONArray locales = new JSONArray();
        for (Locale currentLocale : searchParameters.getLocales()) {
            locales.put(DefaultTypeConverter.INSTANCE.convert(String.class, currentLocale));
        }
        if (locales.length() == 0) {
            locales.put(I18NUtil.getLocale());
        }
        body.put("locales", locales);

        JSONArray templates = new JSONArray();
        for (String templateName : searchParameters.getQueryTemplates().keySet()) {
            JSONObject template = new JSONObject();
            template.put("name", templateName);
            template.put("template", searchParameters.getQueryTemplates().get(templateName));
            templates.put(template);
        }
        body.put("templates", templates);

        JSONArray allAttributes = new JSONArray();
        for (String attribute : searchParameters.getAllAttributes()) {
            allAttributes.put(attribute);
        }
        body.put("allAttributes", allAttributes);

        body.put("defaultFTSOperator", searchParameters.getDefaultFTSOperator());
        body.put("defaultFTSFieldOperator", searchParameters.getDefaultFTSFieldOperator());
        body.put("queryConsistency", searchParameters.getQueryConsistency());
        if (searchParameters.getMlAnalaysisMode() != null) {
            body.put("mlAnalaysisMode", searchParameters.getMlAnalaysisMode().toString());
        }
        body.put("defaultNamespace", searchParameters.getNamespace());

        JSONArray textAttributes = new JSONArray();
        for (String attribute : searchParameters.getTextAttributes()) {
            textAttributes.put(attribute);
        }
        body.put("textAttributes", textAttributes);

        final int maximumResults = maxResults; //just needed for the final parameter

        return (ResultSet) postSolrQuery(httpClient, url.toString(), body,
                new SolrJsonProcessor<SolrJSONResultSet>() {

                    @Override
                    public SolrJSONResultSet getResult(JSONObject json) {
                        return new SolrJSONResultSet(json, searchParameters, nodeService, nodeDAO, limitBy,
                                maximumResults);
                    }

                }, spellCheckQueryStr);
    } catch (UnsupportedEncodingException e) {
        throw new LuceneQueryParserException("", e);
    } catch (HttpException e) {
        throw new LuceneQueryParserException("", e);
    } catch (IOException e) {
        throw new LuceneQueryParserException("", e);
    } catch (JSONException e) {
        throw new LuceneQueryParserException("", e);
    }
}

From source file:org.olat.core.util.i18n.I18nManager.java

private final String getLocalizedString(String bundleName, String key, Object[] args, Locale locale,
        boolean overlayEnabled, boolean fallBackToDefaultLocale, boolean fallBackToFallbackLocale,
        boolean resolveRecursively, boolean allowDecoration, int recursionLevel) {
    String msg = null;//from   w w w .java  2 s .  co m
    Properties properties = null;
    // a) If the overlay is enabled, lookup first in the overlay property
    // file
    if (overlayEnabled) {

        Locale overlayLocale = I18nModule.getOverlayLocales().get(locale);
        if (overlayLocale != null) {
            properties = getProperties(overlayLocale, bundleName, resolveRecursively, recursionLevel);
            if (properties != null) {
                msg = properties.getProperty(key);
                //               if (log.isDebug() && msg == null) {
                //                  log.debug("Key::" + key + " not found in overlay::" + I18nModule.getOverlayName() + " for bundle::" + bundleName
                //                        + " and locale::" + locale.toString(), null);
                //               }
            }
        }
    }
    // b) Otherwhise lookup in the regular bundle
    if (msg == null) {
        properties = getProperties(locale, bundleName, resolveRecursively, recursionLevel);
        // if LocalStrings File does not exist -> return error msg on screen
        // / fallback to default language
        if (properties == null) {
            if (Settings.isDebuging()) {
                log.warn(FILE_NOT_FOUND_ERROR_PREFIX + "! locale::" + locale.toString() + ", path::"
                        + bundleName, null);
            }
        } else {
            msg = properties.getProperty(key);
        }
    }

    // The following fallback behaviour is similar to
    // java.util.ResourceBundle
    if (msg == null) {
        if (log.isDebug()) {
            log.debug("Key::" + key + " not found for bundle::" + bundleName + " and locale::"
                    + locale.toString(), null);
        }
        // Fallback on the language if the locale has a country and/or a
        // variant
        // de_DE_variant -> de_DE -> de
        // Only after having all those checked we will fallback to the
        // default language
        // 1. Check on variant
        String variant = locale.getVariant();
        if (!variant.equals("")) {
            Locale newLoc = I18nModule.getAllLocales().get(locale.getLanguage() + "_" + locale.getCountry());
            if (newLoc != null)
                msg = getLocalizedString(bundleName, key, args, newLoc, overlayEnabled, false,
                        fallBackToFallbackLocale, resolveRecursively, recursionLevel);
        }
        if (msg == null) {
            // 2. Check on country
            String country = locale.getCountry();
            if (!country.equals("")) {
                Locale newLoc = I18nModule.getAllLocales().get(locale.getLanguage());
                if (newLoc != null)
                    msg = getLocalizedString(bundleName, key, args, newLoc, overlayEnabled, false,
                            fallBackToFallbackLocale, resolveRecursively, recursionLevel);
            }
            // else we have an original locale with only a language given ->
            // no language specific fallbacks anymore
        }
    }

    if (msg == null) {
        // Message still empty? Use fallback to default language?
        // yes: return the call applied with the olatcore default locale
        // no: return null to indicate nothing was found so that callers may
        // use fallbacks
        if (fallBackToDefaultLocale) {
            return getLocalizedString(bundleName, key, args, I18nModule.getDefaultLocale(), overlayEnabled,
                    false, fallBackToFallbackLocale, resolveRecursively, recursionLevel);
        } else {
            if (fallBackToFallbackLocale) {
                // fallback to fallback locale
                Locale fallbackLocale = I18nModule.getFallbackLocale();
                if (fallbackLocale.equals(locale)) {
                    // finish when when already in fallback locale
                    if (isLogDebugEnabled()) {
                        logWarn("Could not find translation for bundle::" + bundleName + " and key::" + key
                                + " ; not even in default or fallback packages", null);
                    }
                    return null;
                } else {
                    return getLocalizedString(bundleName, key, args, fallbackLocale, overlayEnabled, false,
                            false, resolveRecursively, recursionLevel);
                }
            } else {
                return null;
            }
        }
    }
    // When caching not enabled we need to check for keys contained in this
    // value. In caching mode this is already done while loading the
    // properties
    // file
    if (resolveRecursively && (!cachingEnabled || properties != null)) {
        msg = resolveValuesInternalKeys(locale, bundleName, key, properties, overlayEnabled, recursionLevel,
                msg);
    }

    // Add markup code to identify translated strings
    if (allowDecoration && isCurrentThreadMarkLocalizedStringsEnabled()
            && !bundleName.startsWith(BUNDLE_INLINE_TRANSLATION_INTERCEPTOR)
            && !bundleName.startsWith(BUNDLE_EXCEPTION) && isInlineTranslationEnabledForKey(bundleName, key)) {
        // identifyer consists of bundle name and key and an id to
        // distinguish multiple translations of the same key
        String identifyer = bundleName + ":" + key + ":" + CodeHelper.getRAMUniqueID();
        msg = IDENT_PREFIX + identifyer + IDENT_START_POSTFIX + msg + IDENT_PREFIX + identifyer
                + IDENT_END_POSTFIX;
    }
    // Add the the {0},{1} arguments to the GUI message
    if (args == null) {
        return msg;
    } else {
        // Escape single quotes with single quotes. Single quotes have special meaning in MessageFormat
        // See OLAT-5107, OLAT-5756
        if (msg.indexOf("'") > -1) {
            msg = msg.replaceAll("'", "''");
        }
        return MessageFormat.format(msg, args);
    }
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get page accounts attached to the owner of the current access token.
 * /* www  .j  a  v  a 2  s .c  o  m*/
 * @param locale
 * @return JSONObject
 * @throws Exception
 */
private JSONObject getPageAccounts(Locale locale) throws Exception {

    String apiUri = "/me/accounts";

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    return getResponseJson(getHttpGet(apiUri, params));
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get home timeline./*from  w w w. j a v  a  2 s. c  om*/
 * 
 * @param since
 * @param until
 * @param limit
 * @param locale
 * @param isUnixTime
 * @return list of FacebookPost objects
 * @throws Exception
 */
private List<FacebookPost> getHomeTimeline(long since, long until, int limit, Locale locale, boolean isUnixTime)
        throws Exception {

    String apiUri = "/me/home";

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    // set page parameters
    setTimeBasedPageParams(params, since, until, limit, isUnixTime);

    return populatePostList(localeParam, getResponseJson(getHttpGet(apiUri, params)));
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get a post corresponding to given post ID.
 *
 * @param postId/*w  ww.j  a  va2s.  c o  m*/
 * @param locale
 * @return FacebookPost
 * @throws Exception
 */
private FacebookPost getPost(String postId, Locale locale) throws Exception {

    // throw an exception if post ID is invalid
    if (StringHelper.isEmpty(postId) == true) {
        throw new SystemException("Invalid post ID.");
    }

    String apiUri = "/" + postId;

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    return populatePostBean(localeParam, getResponseJson(getHttpGet(apiUri, params)));
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get a Facebook photo object.//from   w  ww  .  j  a  va2 s  .  c  o  m
 * 
 * @param photoId
 * @param locale
 * @return FacebookPhoto
 * @throws Exception
 */
private FacebookPhoto getPhoto(String photoId, Locale locale) throws Exception {

    // throw an exception if photo ID is invalid
    if (StringHelper.isEmpty(photoId) == true) {
        throw new SystemException("Invalid photo ID.");
    }

    String apiUri = "/" + photoId;

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    return populatePhotoBean(localeParam, getResponseJson(getHttpGet(apiUri, params)));
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get a note corresponding to given note ID.
 * //from ww  w  .j av a2 s  .  c o  m
 * @param noteId
 * @param locale
 * @return FacebookNote
 * @throws Exception
 */
private FacebookNote getNote(String noteId, Locale locale) throws Exception {

    // throw an exception if note ID is invalid
    if (StringHelper.isEmpty(noteId) == true) {
        throw new SystemException("Invalid note ID.");
    }

    String apiUri = "/" + noteId;

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    return populateNoteBean(localeParam, getResponseJson(getHttpGet(apiUri, params)), null, null);
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Return a raw JSON object representing a Facebook object.
 * /*w w w  .j ava2s. c  om*/
 * @param facebookObjectId
 * @param locale
 * @return JSONObject
 * @throws Exception
 */
private JSONObject getFacebookObject(String facebookObjectId, Locale locale) throws Exception {

    // throw an exception if Facebook object ID is invalid
    if (StringHelper.isEmpty(facebookObjectId) == true) {
        throw new SystemException("Invalid Facebook object ID.");
    }

    String apiUri = "/" + facebookObjectId;

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    return getResponseJson(getHttpGet(apiUri, params));
}

From source file:illab.nabal.proxy.FacebookProxy.java

/**
 * Get groups./*from www  .j  av a2 s . c  o m*/
 * 
 * @param userIdentifier
 * @param locale
 * @return JSONObject
 * @throws Exception
 */
private JSONObject getGroups(String userIdentifier, int limit, int offset, Locale locale) throws Exception {

    // throw an exception if user identifier is invalid
    if (StringHelper.isEmpty(userIdentifier) == true) {
        throw new SystemException("Invalid user identifier.");
    }

    String apiUri = "/" + userIdentifier + "/groups";

    // set system locale if none given
    Locale localeParam = locale;
    if (localeParam == null)
        localeParam = Util.getSystemLocale();

    List<NameValuePair> params = ParameterHelper.addAllParams(
            new BasicNameValuePair("access_token", mFacebookContext.getAccessToken()),
            new BasicNameValuePair("locale", localeParam.toString()));

    // set page parameters
    setPageOffsetParams(params, limit, offset);

    return getResponseJson(getHttpGet(apiUri, params));
}