/* * 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; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.logging.Log; import org.eurekastreams.commons.actions.InlineExecutionStrategyExecutor; import org.eurekastreams.commons.actions.TaskHandlerExecutionStrategy; import org.eurekastreams.commons.actions.context.PrincipalActionContext; import org.eurekastreams.commons.actions.context.TaskHandlerActionContext; import org.eurekastreams.commons.exceptions.ExecutionException; import org.eurekastreams.commons.exceptions.ValidationException; import org.eurekastreams.commons.logging.LogFactory; import org.eurekastreams.server.domain.Person; import org.eurekastreams.server.persistence.PersonMapper; import org.eurekastreams.server.service.actions.strategies.ResourcePersistenceStrategy; import org.eurekastreams.server.service.actions.strategies.UpdaterStrategy; /** * Persist a resource. * * @param <T> * the type of resource to persist */ public class PersistResourceExecution<T> implements TaskHandlerExecutionStrategy<PrincipalActionContext> { /** * Logger. */ private final Log log = LogFactory.make(); /** * the person creator factory. the PersistResourceAction class depends on an object of the same type, but spring * wouldn't allow me to instantiate an object of the same type that it is currently instantiating, so i get around * that by using the factory. * */ private final CreatePersonActionFactory factory; /** * the person mapper. * */ private final PersonMapper personMapper; /** * the persistence strategy. */ private final ResourcePersistenceStrategy<T> persistenceStrategy; /** * the strategy used to set the resource's properties. */ private final UpdaterStrategy updater; /** * Constructor. * * @param inPersonMapper * The PersonMapper. * @param inFactory * The CreatePersonActionFactory. * @param inUpdater * The UpdaterStrategy. * @param inPersistenceStrategy * The ResourcePersistenceStrategy to be used. */ @SuppressWarnings("unchecked") public PersistResourceExecution(final PersonMapper inPersonMapper, final CreatePersonActionFactory inFactory, final UpdaterStrategy inUpdater, final ResourcePersistenceStrategy inPersistenceStrategy) { personMapper = inPersonMapper; factory = inFactory; updater = inUpdater; persistenceStrategy = inPersistenceStrategy; } @Override public Serializable execute(final TaskHandlerActionContext<PrincipalActionContext> inActionContext) throws ExecutionException { try { // convert the params to a map Map<String, Serializable> fields = (Map<String, Serializable>) inActionContext.getActionContext() .getParams(); Map<String, Serializable> newFields = new HashMap<String, Serializable>(); // make sure all lists have attached, existing domain objects for (String key : fields.keySet()) { // replace sets of Person new or attached entities (as opposed to detached entities) if (fields.get(key) instanceof Set) { Set<Person> verifiedPersons = reformatSet(inActionContext, (Set<Person>) fields.get(key)); newFields.put(key, (Serializable) verifiedPersons); } else { newFields.put(key, fields.get(key)); } } // get the resource to persist T resource = persistenceStrategy.get(inActionContext, newFields); // set the properties on the resource updater.setProperties(resource, newFields); // persist persistenceStrategy.persist(inActionContext, newFields, resource); return (Serializable) resource; } catch (Exception e) { if (e instanceof ValidationException) { ValidationException ve = (ValidationException) e; Set<Entry<String, String>> errors = ve.getErrors().entrySet(); StringBuffer b = new StringBuffer(); for (Entry<String, String> entry : errors) { b.append(entry.getKey() + ":" + entry.getValue() + " "); } log.error(b.toString()); } throw new ExecutionException(e); } } /** * Returns a set of people that are created in DB is needed. * * @param inActionContext * the action context * @param requestedPersons * The set of requested persons. * @return Set of "created" person objects. * @throws Exception * If error occurs. */ private Set<Person> reformatSet(final TaskHandlerActionContext<PrincipalActionContext> inActionContext, final Set<Person> requestedPersons) throws Exception { // create the coordinator lists Set<Person> verifiedPersons = new HashSet<Person>(); // if a requested coordinator is not already in the database, // then create a new Person object for (Person requestedPerson : requestedPersons) { Person verfiedCoordinator = personMapper.findByAccountId(requestedPerson.getAccountId()); if (verfiedCoordinator == null) { final HashMap<String, Serializable> personData = requestedPerson.getProperties(); // to avoid a circular dependency, must get a new person creator from the factory rather than // have it injected by spring PersistResourceExecution<Person> personCreator = factory.getCreatePersonAction(personMapper, updater); verfiedCoordinator = (Person) new InlineExecutionStrategyExecutor().execute(personCreator, personData, inActionContext); } verifiedPersons.add(verfiedCoordinator); } return verifiedPersons; } }