/* * Copyright (c) 2010-2011 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.action.execution.feed; import java.io.Serializable; import java.util.HashMap; import org.eurekastreams.commons.actions.Action; import org.eurekastreams.commons.actions.ExecutionStrategy; import org.eurekastreams.commons.actions.InlineExecutionStrategyExecutor; import org.eurekastreams.commons.actions.TaskHandlerExecutionStrategy; import org.eurekastreams.commons.actions.context.Principal; import org.eurekastreams.commons.actions.context.PrincipalActionContext; import org.eurekastreams.commons.actions.context.TaskHandlerActionContext; import org.eurekastreams.commons.actions.context.service.ServiceActionContext; import org.eurekastreams.commons.exceptions.ValidationException; import org.eurekastreams.server.action.request.feed.DeleteFeedSubscriptionRequest; import org.eurekastreams.server.action.request.stream.PostActivityRequest; import org.eurekastreams.server.domain.EntityType; import org.eurekastreams.server.domain.stream.ActivityDTO; import org.eurekastreams.server.domain.stream.ActivityVerb; import org.eurekastreams.server.domain.stream.BaseObjectType; import org.eurekastreams.server.domain.stream.StreamEntityDTO; import org.eurekastreams.server.domain.stream.plugins.Feed; import org.eurekastreams.server.domain.stream.plugins.FeedSubscriber; import org.eurekastreams.server.persistence.mappers.UpdateMapper; import org.eurekastreams.server.persistence.mappers.db.GetFeedByUrlOrCreateMapper; import org.eurekastreams.server.persistence.mappers.db.GetFeedSubscriberOrCreateMapper; import org.eurekastreams.server.persistence.mappers.requests.GetFeedByUrlRequest; import org.eurekastreams.server.persistence.mappers.requests.GetFeedSubscriberRequest; import org.eurekastreams.server.persistence.mappers.requests.PersistenceRequest; import org.eurekastreams.server.service.actions.strategies.activity.plugins.GetEntityIdForFeedSubscription; /** * Adds a feed to a user or group. Also handles updates, since the conf settings are cleared and reset regardless and * the mappers handle finding and creating for me. Booya. * */ public class AddFeedToEntityExecution implements TaskHandlerExecutionStrategy<PrincipalActionContext> { /** * Update mapper. */ private final UpdateMapper<Feed> updateMapper; /** * Get feed mapper. */ private final GetFeedByUrlOrCreateMapper getMapper; /** * Person mapper. */ private final GetEntityIdForFeedSubscription getEntityId; /** * Get feed subscriber mapper. */ private final GetFeedSubscriberOrCreateMapper getFeedSubscriberMapper; /** * Get the title for a feed. */ private final ExecutionStrategy getTitleFromFeed; /** * Delete the existing feed sub is this is an edit. */ private final Action deleteFeedSub; /** * The entity type. */ private final EntityType type; /** * The get activity executor. */ private final TaskHandlerExecutionStrategy postActivityExecutor; /** * Default constructor. * * @param inUpdateMapper * update mapper. * @param inGetMapper * mapper to get the feed or create it if it doesnt exist. * @param inGetEntityId * get entity mapper. * @param inGetFeedSubscriberMapper * get feed sub mapper. * @param inGetTitleFromFeed * get the title from a feed. * @param inDeleteFeedSub * delete feed sub mapper. * @param inType * entity type. * @param inPostActivityExecutor * post executor. */ @SuppressWarnings("unchecked") public AddFeedToEntityExecution(final UpdateMapper<Feed> inUpdateMapper, final GetFeedByUrlOrCreateMapper inGetMapper, final GetEntityIdForFeedSubscription inGetEntityId, final GetFeedSubscriberOrCreateMapper inGetFeedSubscriberMapper, final ExecutionStrategy inGetTitleFromFeed, final Action inDeleteFeedSub, final EntityType inType, final TaskHandlerExecutionStrategy inPostActivityExecutor) { updateMapper = inUpdateMapper; getMapper = inGetMapper; getEntityId = inGetEntityId; getFeedSubscriberMapper = inGetFeedSubscriberMapper; getTitleFromFeed = inGetTitleFromFeed; deleteFeedSub = inDeleteFeedSub; type = inType; postActivityExecutor = inPostActivityExecutor; } /** * Perform action. * * @param context * The ActionContext for this execution * @return Serializable result */ public Serializable execute(final TaskHandlerActionContext<PrincipalActionContext> context) { HashMap<String, Serializable> values = (HashMap<String, Serializable>) context.getActionContext().getParams(); ValidationException exception = new ValidationException(); // Loop through and see if any key/values are required through the use of the // REQUIRED: prefix. for (String key : values.keySet()) { if (key.contains("REQUIRED:")) { String keyLookup = key.split("REQUIRED:")[1]; if (!values.containsKey(keyLookup) || values.get(keyLookup) == null || (values.get(keyLookup) instanceof String && ((String) values.get(keyLookup)).equals(""))) { exception.addError(keyLookup, (String) values.get(key)); } } } // Make sure they checked the TOS. if (!(Boolean) values.get("EUREKA:TOS")) { exception.addError("EUREKA:TOS", "In order to use this plugin you must agree to the terms of use."); } // If you found any errors, error. if (exception.getErrors().size() > 0) { throw exception; } String group = ""; if (values.containsKey("EUREKA:GROUP")) { group = (String) values.get("EUREKA:GROUP"); } Principal principal = context.getActionContext().getPrincipal(); if (values.containsKey("EUREKA:FEEDSUBID")) { ServiceActionContext deleteAC = new ServiceActionContext(new DeleteFeedSubscriptionRequest((Long) values.get("EUREKA:FEEDSUBID"), group), principal); deleteFeedSub.getExecutionStrategy().execute(deleteAC); } // Put the user in the values hash map so it's on equal footing for the strategies. values.put("EUREKA:USER", principal.getAccountId()); // TODO BUG: context does not contain the right parameters for this execution strategy. // Perhaps a new request object needs to be created? Moving on for now. ServiceActionContext getFeedContext = new ServiceActionContext(values.get("EUREKA:FEEDURL"), principal); String title = (String) getTitleFromFeed.execute(getFeedContext); // Find or create the feed. GetFeedByUrlRequest request = new GetFeedByUrlRequest((Long) values.get("EUREKA:PLUGINID"), (String) values.get("EUREKA:FEEDURL")); Feed feed = getMapper.execute(request); feed.setTitle(title); // And now find or create the subscriber. FeedSubscriber feedSubscriber = getFeedSubscriberMapper.execute(new GetFeedSubscriberRequest(feed.getId(), getEntityId .getEntityId(values), type, principal.getId())); // Add any non system key/value pairs to the feed subscribers conf settings. feedSubscriber.getConfSettings().clear(); for (String key : values.keySet()) { if (!key.contains("REQUIRED:") && !key.contains("EUREKA:")) { feedSubscriber.getConfSettings().put(key, values.get(key)); } } ActivityDTO activity = new ActivityDTO(); HashMap<String, String> props = new HashMap<String, String>(); activity.setBaseObjectProperties(props); String content = "%EUREKA:ACTORNAME% configured the " + values.get("EUREKA:PLUGINTITLE") + " stream plugin"; activity.getBaseObjectProperties().put("content", content); StreamEntityDTO destination = new StreamEntityDTO(); if (type.equals(EntityType.PERSON)) { destination.setUniqueIdentifier(principal.getAccountId()); } else { destination.setUniqueIdentifier(group); } destination.setType(type); activity.setDestinationStream(destination); activity.setBaseObjectType(BaseObjectType.NOTE); activity.setVerb(ActivityVerb.POST); new InlineExecutionStrategyExecutor() .execute(postActivityExecutor, new PostActivityRequest(activity), context); updateMapper.execute(new PersistenceRequest<Feed>(feed)); return Boolean.TRUE; } }