private void handleUserActionDispatched(UserActionEntity userAction) { String entityId = userAction.getEntityId(); // Mark user's action as being dispatched mEntityIdToDispatchedUserActionsMap.get(entityId).add(userAction); mDispatchedUserActionsCount++; }
private Map<String, List<UserActionEntity>> mapEntityIdsToSortedUserActions(List<UserActionEntity> userActions) { Map<String, List<UserActionEntity>> resultMap = new HashMap<>(); String entityId; // map entities to user actions that affect them for (UserActionEntity userAction : userActions) { entityId = userAction.getEntityId(); if (!resultMap.containsKey(entityId)) { resultMap.put(entityId, new ArrayList<UserActionEntity>(1)); } resultMap.get(entityId).add(userAction); } // independently sort user actions for each entity for (String sortedEntityId : resultMap.keySet()) { Collections.sort(resultMap.get(sortedEntityId), new UserActionsComparator()); } return resultMap; }
@Override public void onUserActionAdded(UserActionEntity userAction) { RequestDetailsFragment fragment = RequestDetailsFragment.newInstance(userAction.getEntityId()); mMainFrameHelper.replaceFragment(fragment, false, true); } });
public void cacheUserAction(UserActionEntity userAction) { mLogger.d(TAG, "cacheUserAction(); user action: " + userAction); ContentValues userActionCV = new ContentValues(6); userActionCV.put(IDoCareContract.UserActions.COL_TIMESTAMP, userAction.getDatetime()); userActionCV.put(IDoCareContract.UserActions.COL_ENTITY_TYPE, userAction.getEntityType()); userActionCV.put(IDoCareContract.UserActions.COL_ENTITY_ID, userAction.getEntityId()); userActionCV.put(IDoCareContract.UserActions.COL_ENTITY_PARAM, userAction.getEntityParam()); userActionCV.put(IDoCareContract.UserActions.COL_ACTION_TYPE, userAction.getActionType()); userActionCV.put(IDoCareContract.UserActions.COL_ACTION_PARAM, userAction.getActionParam()); mContentResolver.insert( IDoCareContract.UserActions.CONTENT_URI, userActionCV ); }
/** * Some user actions, when uploaded to the server, change entities IDs (e.g. newly created * requests assigned permanent IDs during uploading). This method ensures that the internal * IDs managed by this dispatcher stay in sync with these changes */ private void ensureConsistentEntityIds(UserActionEntity userAction) { synchronized (DISPATCHER_LOCK) { if (isCreateRequestUserAction(userAction)) { // The uploaded action was of type "create request", which means that the ID of this // request has changed... String oldId = userAction.getEntityId(); // There should be mapping from old entity ID to the new entity ID String newId = getPermanentEntityId(userAction.getEntityId()); // Now change IDs in all the data structures changeIdsInMap(mEntityIdToNonDispatchedUserActionsMap, oldId, newId); changeIdsInMap(mEntityIdToDispatchedUserActionsMap, oldId, newId); if (mEntityIdToStallFlagMap.containsKey(oldId)) { mEntityIdToStallFlagMap.put(newId, mEntityIdToStallFlagMap.remove(oldId)); } if (mCompletedEntityIds.contains(oldId)) { mCompletedEntityIds.remove(oldId); mCompletedEntityIds.add(newId); } // TODO: also need to change IDs in database!!!! } } }
public static CloseRequestUserActionEntity fromUserAction(UserActionEntity userAction) { Gson gson = new Gson(); // TODO: this is inefficient ActionParam actionParam = gson.fromJson(userAction.getActionParam(), ActionParam.class); return new CloseRequestUserActionEntity( userAction.getDatetime(), userAction.getEntityId(), actionParam.closedBy, actionParam.closedComment, StringUtils.commaSeparatedStringToList(actionParam.closedPictures)); }
/** * Let the dispatcher know that one of the dispatched actions have been uploaded to the * server */ public void notifyUserActionSyncComplete(UserActionEntity userAction, boolean isSuccess) { mLogger.d(TAG, "notifyUserActionSyncComplete(); user action: " + userAction + "; is success: " + isSuccess); synchronized (DISPATCHER_LOCK) { String entityId = userAction.getEntityId(); if (!mEntityIdToDispatchedUserActionsMap.get(entityId).contains(userAction)) { throw new IllegalStateException("user action is not in the dispatched list"); } // Remove the action from the dispatched list mEntityIdToDispatchedUserActionsMap.get(entityId).remove(userAction); if (isStallingAction(userAction)) { // if the action was of "stalling" type - clear entity's stall flag mEntityIdToStallFlagMap.get(entityId).set(false); // there might be threads waiting for stalled action to complete - notify them DISPATCHER_LOCK.notifyAll(); } cleanIfNoMoreActionsForEntity(entityId); if (isSuccess) { // There are user actions that their uploading changes IDs of entities (e.g. new requests // get permanent IDs assigned by the server) - account for this change ensureConsistentEntityIds(userAction); } } }
public static VoteForRequestUserActionEntity fromUserAction(UserActionEntity userAction) { return new VoteForRequestUserActionEntity( userAction.getDatetime(), userAction.getEntityId(), getVoteTypeFromUserAction(userAction) ); }
public static PickUpRequestUserActionEntity fromUserAction(UserActionEntity userAction) { return new PickUpRequestUserActionEntity( userAction.getDatetime(), userAction.getEntityId(), userAction.getActionParam()); }
private List<RequestEntity> applyUserActionsToRequests(List<RequestEntity> requests) { List<UserActionEntity> userActions = mUserActionsRetriever.getAllUserActions(); if (userActions.isEmpty() || requests.isEmpty()) return requests; Collections.sort(requests, mComparator); // sort in order to be able to use binary search List<RequestEntity> updatedRequests = new ArrayList<>(requests); RequestEntity updatedRequest; for (UserActionEntity userAction : userActions) { if (mUserActionsToRequestsApplier.isUserActionAffectingRequest(userAction)) { // find the request affected by user action, and if it is found - apply the action to it int affectedEntityPos = Collections.binarySearch( requests, RequestEntity.getBuilder().setId(userAction.getEntityId()).build(), mComparator); if (affectedEntityPos >= 0) { updatedRequest = mUserActionsToRequestsApplier.applyUserActionToRequest( userAction, requests.get(affectedEntityPos)); updatedRequests.set(affectedEntityPos, updatedRequest); } } } return updatedRequests; }
/** * * @param userAction the user action which should be applied to request * @param requestEntity the request on which to apply the user action * @return new request which is the merge of the provided request and the information from * user action * @throws IllegalArgumentException if the provided user action is not applicable to the * provided request */ public RequestEntity applyUserActionToRequest(@NonNull UserActionEntity userAction, @NonNull RequestEntity requestEntity) { if (!userAction.getEntityType().equals(UserActions.ENTITY_TYPE_REQUEST) || !userAction.getEntityId().equals(requestEntity.getId())) { throw new IllegalArgumentException("user action is not related to the request"); } if (userAction.getActionType().equals(UserActions.ACTION_TYPE_CLOSE_REQUEST)) { return closeRequest(CloseRequestUserActionEntity.fromUserAction(userAction), requestEntity); } else if (userAction.getActionType().equals(UserActions.ACTION_TYPE_PICKUP_REQUEST)) { return pickUpRequest(PickUpRequestUserActionEntity.fromUserAction(userAction), requestEntity); } else if (userAction.getActionType().equals(UserActions.ACTION_TYPE_CREATE_REQUEST)) { // this action is just a "marker" - the actual data has already been written to requests cache return requestEntity; } else if (userAction.getActionType().equals(UserActions.ACTION_TYPE_VOTE_FOR_REQUEST)) { return voteForRequest(VoteForRequestUserActionEntity.fromUserAction(userAction), requestEntity); } else { throw new RuntimeException("invalid user action: " + userAction); } }
String entityId = userAction.getEntityId();
private void assertUserActionsEqual(UserActionEntity actual, UserActionEntity expected) { assertThat(actual.getActionParam(), is(expected.getActionParam())); assertThat(actual.getActionType(), is(expected.getActionType())); assertThat(actual.getEntityId(), is(expected.getEntityId())); assertThat(actual.getEntityParam(), is(expected.getEntityParam())); assertThat(actual.getEntityType(), is(expected.getEntityType())); assertThat(actual.getDatetime(), is(expected.getDatetime())); }
case IDoCareContract.UserActions.ACTION_TYPE_CREATE_REQUEST: mRequestsSyncer.syncRequestCreated(userAction.getEntityId()); break;
public static Builder newBuilder(UserActionEntity userAction) { return newBuilder() .setId(userAction.getActionId()) .setTimestamp(userAction.getDatetime()) .setEntityType(userAction.getEntityType()) .setEntityId(userAction.getEntityId()) .setEntityParam(userAction.getEntityParam()) .setActionType(userAction.getActionType()) .setActionParam(userAction.getActionParam()); }