/* * Copyright (c) 2009-2010 Lockheed Martin Corporation * * 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.eurekastreams.server.service.opensocial.spi; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Future; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shindig.auth.SecurityToken; import org.apache.shindig.common.util.ImmediateFuture; import org.apache.shindig.protocol.DataCollection; import org.apache.shindig.protocol.ProtocolException; import org.apache.shindig.social.opensocial.spi.AppDataService; import org.apache.shindig.social.opensocial.spi.GroupId; import org.apache.shindig.social.opensocial.spi.UserId; import org.eurekastreams.commons.actions.context.service.ServiceActionContext; import org.eurekastreams.commons.actions.service.ServiceAction; import org.eurekastreams.commons.server.service.ActionController; import org.eurekastreams.server.action.principal.OpenSocialPrincipalPopulator; import org.eurekastreams.server.action.request.opensocial.DeleteAppDataRequest; import org.eurekastreams.server.action.request.opensocial.GetAppDataRequest; import org.eurekastreams.server.action.request.opensocial.UpdateAppDataRequest; import org.eurekastreams.server.domain.dto.AppDataDTO; import com.google.inject.Inject; import com.google.inject.name.Named; /** * Class that implements the Shindig Application Data Service endpoint. * */ public class AppDataServiceImpl implements AppDataService { /** * Logger. */ private Log log = LogFactory.getLog(AppDataServiceImpl.class); /** * Instance of the service action on which requests will be made. */ private ServiceAction getAppDataAction; /** * Local instance of the ServiceActionController to submit service actions through. */ private ActionController serviceActionController; /** * Local instance of the {@link OpenSocialPrincipalPopulator} for setting up the {@link ServiceActionContext}. */ private OpenSocialPrincipalPopulator openSocialPrincipalPopulator; /** * Instance of the service action for updating data. */ private ServiceAction updateDataAction; /** * Instance of the service action for deleting data. */ private ServiceAction deleteDataAction; /** * This is the main constructor for the AppDataServiceImpl class which allows Guice to inject a Spring loaded action * to provide the connection to the backend database. * * @param inGetAppDataAction * - Action that will perform the database mapping for AppDataServiceImpl. This approach allows the * implementation to maintain the transactional nature of the actions in non-shindig integrated actions. * @param inServiceActionController * - instance of the service action controller responsible for loading and executing * {@link ServiceAction}. * @param inOpenSocialPrincipalPopulator * - instance of the {@link OpenSocialPrincipalPopulator} for retrieving OpenSocial {@link Principal} * objects. * @param inUpdateAction * - Action that will perform the update database mapping. * @param inDeleteAction * - Action that will perform the delete database operation. */ @Inject public AppDataServiceImpl(@Named("getAppData") final ServiceAction inGetAppDataAction, final ActionController inServiceActionController, final OpenSocialPrincipalPopulator inOpenSocialPrincipalPopulator, @Named("updateAppData") final ServiceAction inUpdateAction, @Named("deleteAppData") final ServiceAction inDeleteAction) { getAppDataAction = inGetAppDataAction; serviceActionController = inServiceActionController; openSocialPrincipalPopulator = inOpenSocialPrincipalPopulator; updateDataAction = inUpdateAction; deleteDataAction = inDeleteAction; } /** * Delete person method. * * @param userId * - user id of the person's data to delete. * @param groupId * - id of the group that the users belong to - currently unimplemented in OpenSocial js API for Shindig. * @param appId * - id of the application requesting the data to be deleted. * @param fields * - fields to delete. * @param token * - security token for the request. * * @return void */ public Future<Void> deletePersonData(final UserId userId, final GroupId groupId, final String appId, final Set<String> fields, final SecurityToken token) { log.debug("Entering delete Person data with userId" + userId.getUserId(token) + ", appId " + appId + ", " + fields.size() + ", token appId " + token.getAppId()); try { String userOpenSocialId = userId.getUserId(token); // create the request DeleteAppDataRequest params = new DeleteAppDataRequest(Long.parseLong(appId), userOpenSocialId, fields); // create the context ServiceActionContext context = new ServiceActionContext(params, openSocialPrincipalPopulator .getPrincipal(userOpenSocialId)); // Execute action via service action controller to perform the update. serviceActionController.execute(context, deleteDataAction); } catch (Exception e) { log.error("Error occurred deleting OpenSocial Application Data " + e.toString()); throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); } return ImmediateFuture.newInstance(null); } /** * Get the person data. * * @param userIds * - set of user ids to retrieve person data for. * @param groupId * - id of the group that the users belong to - currently unimplemented in OpenSocial js API for Shindig. * @param appId * - id of the application requesting the data to be deleted. * @param fields * - fields to retrieve. * @param token * - security token for the request. * * @return DataCollection containing the data requested. */ public Future<DataCollection> getPersonData(final Set<UserId> userIds, final GroupId groupId, final String appId, final Set<String> fields, final SecurityToken token) { log.debug("Entering getPerson data with " + userIds.size() + " userIds, appId " + appId + ", " + fields.size() + ", token appId " + token.getAppId()); AppDataDTO currentAppData = null; GetAppDataRequest currentRequest = new GetAppDataRequest(); ServiceActionContext currentContext; Map<String, Map<String, String>> results = new HashMap<String, Map<String, String>>(); try { log.debug("Retrieve userIds"); List<String> currentUserIds = SPIUtils.getUserList(userIds, token); currentRequest.setApplicationId(new Long(appId)); // TODO add in group implementation when Friends list is available. // switch(groupId.getType()) // { // case all: // //TODO Assemble specialized parameters for all Group // break; // case deleted: // //TODO Assemble specialized parameters for deleted Group // break; // case friends: // //TODO Assemble specialized parameters for deleted Group // break; // case groupId: // //TODO Assemble specialized parameters for deleted Group // break; // default: // //Self group // break; // } log.debug("Loop through userIds"); for (String currentUserId : currentUserIds) { currentRequest.setOpenSocialId(currentUserId); currentContext = new ServiceActionContext(currentRequest, openSocialPrincipalPopulator .getPrincipal(currentUserId)); currentAppData = (AppDataDTO) serviceActionController.execute(currentContext, getAppDataAction); if (currentAppData != null) { results.put(currentAppData.getOpenSocialId(), currentAppData.getKeyValuePairs()); } } } catch (Exception e) { log.error("Error occurred retrieving appData " + e.toString()); throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); } DataCollection dc = new DataCollection(results); return ImmediateFuture.newInstance(dc); } /** * Update the person data. * * @param userId * - user id of the person to update data for. * @param groupId * - id of the group that the users belong to - currently unimplemented in OpenSocial js API for Shindig. * @param appId * - id of the application requesting the data to be deleted. * @param fields * - fields to retrieve. * @param values * - values to update the fields with. * @param token * - security token for the request. * * @return void */ public Future<Void> updatePersonData(final UserId userId, final GroupId groupId, final String appId, final Set<String> fields, final Map<String, String> values, final SecurityToken token) { log.debug("Entering getPerson data with userId " + userId.getUserId(token) + ", appId " + appId + ", " + fields.size() + ", Map length " + values.size() + ", token appId " + token.getAppId()); try { String userOpenSocialId = userId.getUserId(token); // create the request UpdateAppDataRequest params = new UpdateAppDataRequest(Long.parseLong(appId), userOpenSocialId, new HashMap<String, String>(values)); // create the context ServiceActionContext context = new ServiceActionContext(params, openSocialPrincipalPopulator .getPrincipal(userOpenSocialId)); // Execute action via service action controller to perform the update. serviceActionController.execute(context, updateDataAction); } catch (Exception e) { log.error("Error occurred updating AppData " + e.toString()); throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); } return ImmediateFuture.newInstance(null); } }