org.wso2.carbon.registry.social.impl.appdata.AppDataManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.registry.social.impl.appdata.AppDataManagerImpl.java

Source

/*
 * Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.wso2.carbon.registry.social.impl.appdata;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.social.api.SocialDataException;
import org.wso2.carbon.registry.social.api.appdata.AppDataManager;
import org.wso2.carbon.registry.social.impl.SocialImplConstants;
import org.wso2.carbon.registry.social.impl.internal.SocialDSComponent;
import org.wso2.carbon.registry.social.impl.people.relationship.RelationshipManagerImpl;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

/**
 * An implementation of the {@link org.wso2.carbon.registry.social.api.appdata.AppDataManager} interface
 * <p>
 * This implementation uses the {@link org.wso2.carbon.registry.core.Registry} to store app data
 * </p>
 * <p>
 * The app data  is stored as a {@link org.wso2.carbon.registry.core.Registry}  {@link org.wso2.carbon.registry.core.Resource}
 * The key-value pairs are stored as resource properties
 * </p>
 * <p>
 * <p/>
 * Each AppData key-value is grouped according to the appId of it
 * </p>
 * <p>
 * Resource path : /{AppData}/{appId}/[key][value]
 * </p>
 */
public class AppDataManagerImpl implements AppDataManager {
    private static Log log = LogFactory.getLog(AppDataManagerImpl.class);
    private Registry registry;
    /* Setting the Registry object */

    public void setRegistry(Registry reg) {
        this.registry = reg;
    }

    /* The Registry object used throughout */

    public Registry getRegistry() throws RegistryException {
        if (this.registry != null) {
            return this.registry;
        } else {
            return SocialDSComponent.getRegistry();
        }
    }

    /**
     * Retrieves app data for the specified user list and group
     *
     * @param userIds A set of userIds whose app data to be retrieved
     * @param groupId The group
     * @param appId   The app
     * @param fields  The fields to return
     * @return A collection of appData for the given user list and group
     * @throws SocialDataException
     */
    public Map<String, Map<String, String>> getPersonData(String[] userIds, String groupId, String appId,
            Set<String> fields) throws SocialDataException {

        List<String> userIdsToFetch = new ArrayList<String>();

        // Check for groupId
        if (SocialImplConstants.GROUP_ID_FRIENDS.equals(groupId)) {
            for (String id : userIds) {
                String[] friendsList = new RelationshipManagerImpl().getRelationshipList(id);
                for (String friend : friendsList) {
                    userIdsToFetch.add(friend);
                }
            }
            userIds = new String[userIdsToFetch.size()];
            userIds = userIdsToFetch.toArray(userIds);
        }
        Map<String, Map<String, String>> personDataMap = new HashMap<String, Map<String, String>>();
        for (String id : userIds) {
            try {
                Map<String, String> data = getAppData(id, appId, fields);
                if (data == null) {
                    //  log.error("No data found for the user " + id);
                    return new HashMap<String, Map<String, String>>();
                }
                personDataMap.put(id, data);
            } catch (RegistryException e) {
                log.error(e.getMessage(), e);
                throw new SocialDataException(
                        "Error while retrieving app data with id " + appId + " for user " + id, e);
            }

        }
        return personDataMap;
    }

    /**
     * Deletes data for the specified user and group
     *
     * @param userId  The userId of the person whose app data to be removed
     * @param groupId The group
     * @param appId   The app
     * @param fields  The fields to delete. Empty implies all
     * @throws SocialDataException
     */

    public void deletePersonData(String userId, String groupId, String appId, Set<String> fields)
            throws SocialDataException {
        try {
            registry = getRegistry();
            Resource appDataResource;
            String appDataResourcePath = SocialImplConstants.APP_DATA_REGISTRY_ROOT + SocialImplConstants.SEPARATOR
                    + appId + SocialImplConstants.SEPARATOR + userId;
            if (registry.resourceExists(appDataResourcePath)) {
                appDataResource = registry.get(appDataResourcePath);
                for (String key : fields) {
                    appDataResource.removeProperty(key);
                }
                registry.put(appDataResourcePath, appDataResource);
            }
        } catch (RegistryException e) {
            log.error(e.getMessage(), e);
            throw new SocialDataException("Error while deleting app data with id " + appId + " for user " + userId,
                    e);
        }
    }

    /**
     * Updates app data for the specified user and group with the new values
     *
     * @param userId  The userId of the person whose app data to be modified
     * @param groupId The group
     * @param appId   The app
     * @param fields  The fields to update. Empty implies all
     * @param values  The new values to set
     * @throws SocialDataException
     */
    public void updatePersonData(String userId, String groupId, String appId, Set<String> fields,
            Map<String, String> values) throws SocialDataException {
        Set<String> fieldsToDelete = new TreeSet<String>();
        // If a field is in the param list but not in the map, that means it is a delete
        // Retrieve the fields to delete
        for (String field : fields) {
            if (!values.containsKey(field)) {
                fieldsToDelete.add(field);
            }
        }
        List<String> userIdsToFetch = new ArrayList<String>();

        // Check for groupId
        if (SocialImplConstants.GROUP_ID_FRIENDS.equals(groupId)) {
            String[] friendsList = new RelationshipManagerImpl().getRelationshipList(userId);
            for (String friend : friendsList) {
                userIdsToFetch.add(friend);
            }
        } else {
            userIdsToFetch.add(userId);
        }
        for (String id : userIdsToFetch) {
            // Update the fields
            savePersonAppData(userId, appId, values, true);
            // Deletes the fields which are not in the Map but in the param list
            deletePersonData(userId, groupId, appId, fieldsToDelete);
        }
    }

    /**
     * Save app data for the specified user with the given values
     *
     * @param userId The userId of the person whose app data to be modified
     * @param appId  The app
     * @param values The new values to set
     * @throws SocialDataException
     */
    public void savePersonData(String userId, String appId, Map<String, String> values) throws SocialDataException {
        savePersonAppData(userId, appId, values, false);

    }

    /**
     * Adds/updates the Map of key-value pairs (appData) to the registry resource
     *
     * @param appDataResource The registry resource to add properties
     * @param values          The Map of key-value appData
     * @param isUpdate        true- if required to update the properties
     *                        false- if required to add the properties
     * @return The registry resource with the appData added as properties
     */

    private Resource getAppDataAddedRegistryResource(Resource appDataResource, Map<String, String> values,
            boolean isUpdate) {
        for (Map.Entry<String, String> e : values.entrySet()) { /* for each key in the map */
            if (e.getValue() != null) {
                /* if (isUpdate) {*/
                String oldValue = appDataResource.getProperty(e.getKey());
                if (oldValue != null) {
                    appDataResource.editPropertyValue(e.getKey(), oldValue,
                            e.getValue()); /* edit properties to the resource */
                }
                /* } else {*/
                else {
                    appDataResource.addProperty(e.getKey(), e.getValue()); /* add properties to the resource */
                }
                /* }*/
            }
        }
        return appDataResource;
    }

    /**
     * Persists/update person Appdata as registry reource
     *
     * @param userId   The id of the person to whom the appData belongs to
     * @param appId    The id of the application to which the appData belongs to
     * @param values   The appData key-value pairs
     * @param isUpdate True, if required to update the properties. Else false
     * @throws SocialDataException
     */
    private void savePersonAppData(String userId, String appId, Map<String, String> values, boolean isUpdate)
            throws SocialDataException {
        try {
            registry = getRegistry();
            Resource appDataResource;
            String appDataResourcePath = SocialImplConstants.APP_DATA_REGISTRY_ROOT + SocialImplConstants.SEPARATOR
                    + appId + SocialImplConstants.SEPARATOR + userId;
            if (registry.resourceExists(appDataResourcePath)) {
                appDataResource = registry.get(appDataResourcePath);
            } else {
                appDataResource = registry.newCollection();
            }
            appDataResource = getAppDataAddedRegistryResource(appDataResource, values, isUpdate);
            registry.put(appDataResourcePath, appDataResource);

        } catch (RegistryException e) {
            log.error(e.getMessage(), e);
            throw new SocialDataException("Error while saving app data with id " + appId + " for user " + userId,
                    e);
        }
    }

    /**
     * Fetches AppData for the given userId,appId,fields collection
     *
     * @param userId The id of the person to fetch the AppData
     * @param appId  The appId to of the AppData to fetch
     * @param fields The fields of AppData to fetch
     * @return A Map<String,String> of AppData values
     * @throws RegistryException
     */
    private Map<String, String> getAppData(String userId, String appId, Set<String> fields)
            throws RegistryException {
        Map<String, String> appDataMap = new HashMap<String, String>();
        String appDataPath = SocialImplConstants.APP_DATA_REGISTRY_ROOT + SocialImplConstants.SEPARATOR + appId
                + SocialImplConstants.SEPARATOR + userId;
        Resource appDataResource;

        registry = getRegistry();
        if (registry.resourceExists(appDataPath)) {
            appDataResource = registry.get(appDataPath);
            if (fields != null && fields.size() > 0) {
                for (String key : fields) {
                    String value;
                    if ((value = appDataResource.getProperty(key)) != null) {
                        appDataMap.put(key, value);
                    }
                }
            } else {
                //Handle when fields is null -> get All properties
                // TODO: refactor code
                Properties props = appDataResource.getProperties();

                for (Enumeration propKeys = props.keys(); propKeys.hasMoreElements();) {
                    String key = propKeys.nextElement().toString();
                    String propValue = props.get(key).toString();
                    //TODO: Re-write this code
                    appDataMap.put(key, propValue.substring(1, propValue.length() - 1));
                }
            }
        } else {
            return null;
        }

        return appDataMap;
    }
}