/src/main/java/com/google/ie/business/service/impl/ProjectServiceImpl.java

http://thoughtsite.googlecode.com/ · Java · 384 lines · 236 code · 39 blank · 109 comment · 30 complexity · 1c9389f8a8d79f22c767104b71cc8d25 MD5 · raw file

  1. /* Copyright 2010 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS.
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License
  14. */
  15. package com.google.ie.business.service.impl;
  16. import com.google.appengine.api.datastore.Blob;
  17. import com.google.ie.business.dao.ProjectDao;
  18. import com.google.ie.business.domain.EntityIndex;
  19. import com.google.ie.business.domain.Idea;
  20. import com.google.ie.business.domain.Project;
  21. import com.google.ie.business.domain.User;
  22. import com.google.ie.business.service.EntityIndexService;
  23. import com.google.ie.business.service.IdeaService;
  24. import com.google.ie.business.service.ProjectService;
  25. import com.google.ie.business.service.ServiceConstants;
  26. import com.google.ie.common.audit.AuditManager;
  27. import com.google.ie.common.cache.CacheConstants;
  28. import com.google.ie.common.cache.CacheHelper;
  29. import com.google.ie.common.constants.IdeaExchangeConstants;
  30. import com.google.ie.common.constants.IdeaExchangeErrorCodes;
  31. import com.google.ie.common.exception.SystemException;
  32. import com.google.ie.common.taskqueue.IndexQueueUpdater;
  33. import com.google.ie.dto.RetrievalInfo;
  34. import com.google.ie.web.controller.WebConstants;
  35. import org.apache.commons.lang.StringUtils;
  36. import org.apache.log4j.Logger;
  37. import org.springframework.beans.factory.annotation.Autowired;
  38. import org.springframework.stereotype.Service;
  39. import java.util.Date;
  40. import java.util.HashSet;
  41. import java.util.Iterator;
  42. import java.util.LinkedList;
  43. import java.util.List;
  44. import java.util.Set;
  45. /**
  46. * A service implementation of the ProjectService
  47. *
  48. * @author Charanjeet singh
  49. *
  50. */
  51. @Service
  52. public class ProjectServiceImpl implements ProjectService {
  53. private static final Logger LOGGER = Logger.getLogger(ProjectServiceImpl.class);
  54. private static final int DEFAULT_NO_OF_RECENT_PROJECTS = 3;
  55. @Autowired
  56. private IdeaService ideaService;
  57. @Autowired
  58. private ProjectDao projectDao;
  59. @Autowired
  60. private AuditManager auditManager;
  61. @Autowired
  62. private EntityIndexService entityIndexService;
  63. @Autowired
  64. private IndexQueueUpdater indexQueueUpdater;
  65. public IndexQueueUpdater getIndexQueueUpdater() {
  66. return indexQueueUpdater;
  67. }
  68. public void setIndexQueueUpdater(IndexQueueUpdater indexQueueUpdater) {
  69. this.indexQueueUpdater = indexQueueUpdater;
  70. }
  71. @Override
  72. public Project createOrUpdateProject(Project project, User user) {
  73. /* check for user and idea key. */
  74. if (StringUtils.isBlank(user.getUserKey()) || StringUtils.isBlank(project.getIdeaKey())) {
  75. throw new SystemException(IdeaExchangeErrorCodes.PROJECT_CREATION_FAILURE_EXCEPTION,
  76. IdeaExchangeConstants.Messages.PROJECT_CREATION_FAILURE_MESSAGE);
  77. }
  78. Idea idea = ideaService.getIdeaByKey(project.getIdeaKey());
  79. /*
  80. * We need to check only for saved idea as edit project is possible on
  81. * deleted idea as well
  82. */
  83. if (!idea.getStatus().equals(Idea.STATUS_SAVED)) {
  84. /* Save project details */
  85. long date = System.currentTimeMillis();
  86. /* If project already exists then update it */
  87. if (project.getKey() != null) {
  88. Project projectFromDataStore = getProjectDao().getProject(project.getKey());
  89. projectFromDataStore.setUpdatedOn(new Date(date));
  90. projectFromDataStore.setName(project.getName());
  91. projectFromDataStore.setDescription(project.getDescription());
  92. projectFromDataStore.setLogo(project.getLogo());
  93. project = saveProjectLocal(projectFromDataStore);
  94. } else {
  95. /* If project is newly created */
  96. project.setStatus(Project.STATUS_CREATED);
  97. project.setCreatedOn(new Date(date));
  98. project.setUpdatedOn(new Date(date));
  99. project.setCreatorKey(user.getUserKey());
  100. project = saveProjectLocal(project);
  101. afterProjectCreation(project, user, idea);
  102. }
  103. return project;
  104. }
  105. return null;
  106. }
  107. /**
  108. * Check validity arguments for project creation .
  109. *
  110. * @throws SystemException
  111. */
  112. private boolean checkIfValid(Idea idea) throws SystemException {
  113. /* Check if idea is published. */
  114. if (!idea.getStatus().equals(Idea.STATUS_PUBLISHED)) {
  115. throw new SystemException(
  116. IdeaExchangeErrorCodes.PROJECT_CREATION_FAILURE_UNPUBLISHED_IDEA_EXCEPTION,
  117. IdeaExchangeConstants.Messages.PROJECT_CREATION_FAILURE_UNPUBLISHED_IDEA_MESSAGE);
  118. }
  119. return true;
  120. }
  121. /**
  122. * Save project and index it.
  123. *
  124. * @param project Project to be saved
  125. * @return Saved project
  126. */
  127. private Project saveProjectLocal(Project project) {
  128. project = projectDao.saveProject(project);
  129. if (project != null) {
  130. /*
  131. * Index the entity.Create an EntityIndex object for the entity
  132. * to be indexed and then queue the job to task queue
  133. */
  134. EntityIndex entityIndex = entityIndexService.createEntityIndex(project.getKey());
  135. getIndexQueueUpdater().indexEntity(entityIndex.getKey());
  136. }
  137. return project;
  138. }
  139. /**
  140. * Performs the post project creation activity.
  141. *
  142. * @param project Project entity.
  143. * @param user The User who has created the project.
  144. * @param idea Idea entity on which a project is being created.
  145. *
  146. */
  147. private void afterProjectCreation(Project project, User user, Idea idea) {
  148. LOGGER.info("Project is successfully saved");
  149. /* log the activity into Audit log. */
  150. getAuditManager().audit(user.getUserKey(), project.getKey(),
  151. project.getClass().getName(),
  152. ServiceConstants.AUDIT_ACTION_TYPE_CREATE_PROJECT);
  153. /* Place the idea into recently picked ideas. */
  154. CacheHelper.putObject(CacheConstants.PROJECT_NAMESPACE,
  155. CacheConstants.RECENTLY_PICKED, idea);
  156. addIdeaToRecentlyPickedIdeaListInCache(idea);
  157. }
  158. @SuppressWarnings("unchecked")
  159. private void addIdeaToRecentlyPickedIdeaListInCache(Idea ideaToBeAdded) {
  160. /* Get the list of recently picked ideas from cache */
  161. LinkedList<Idea> ideas = (LinkedList<Idea>) CacheHelper.getObject(
  162. CacheConstants.IDEA_NAMESPACE,
  163. CacheConstants.RECENTLY_PICKED_IDEAS);
  164. if (ideas != null) {
  165. Iterator<Idea> iterator = ideas.iterator();
  166. Idea ideaFromCache = null;
  167. /* Iterate to check whether the list already contains the idea */
  168. while (iterator.hasNext()) {
  169. ideaFromCache = iterator.next();
  170. String ideaKey = ideaFromCache.getKey();
  171. if (ideaKey.equalsIgnoreCase(ideaToBeAdded.getKey())) {
  172. /*
  173. * If idea already exists in the list , move it to the head
  174. */
  175. ideas.remove(ideaFromCache);
  176. ideas.addFirst(ideaFromCache);
  177. CacheHelper.putObject(CacheConstants.IDEA_NAMESPACE,
  178. CacheConstants.RECENTLY_PICKED_IDEAS, ideas,
  179. CacheConstants.RECENTLY_PICKED_IDEAS_EXPIRATION_DELAY);
  180. return;
  181. }
  182. }
  183. }
  184. /* This is executed if the idea does not already exist in cache */
  185. ideaService.addIdeaToListInCache(ideaToBeAdded, CacheConstants.RECENTLY_PICKED_IDEAS,
  186. DEFAULT_NO_OF_RECENT_PROJECTS,
  187. CacheConstants.RECENTLY_PICKED_IDEAS_EXPIRATION_DELAY);
  188. }
  189. @Override
  190. public Blob getImageById(String key) {
  191. Project project = projectDao.getProject(key);
  192. Blob image = project.getLogo();
  193. if (image == null)
  194. return null;
  195. return image;
  196. }
  197. @Override
  198. public Project getDetails(Project project) {
  199. if (project != null && !StringUtils.isBlank(project.getKey())) {
  200. LOGGER.debug("Retrieving details for the project with key=" + project.getKey());
  201. project = projectDao.getProject(project.getKey());
  202. return project;
  203. }
  204. throw new SystemException(IdeaExchangeErrorCodes.PROJECT_DETAILS_EXCEPTION,
  205. IdeaExchangeConstants.Messages.PROJECT_DETAILS_EXCEPTION_MESSAGE);
  206. }
  207. @Override
  208. public List<Project> listProjects(RetrievalInfo retrievalInfo) {
  209. /* Fetch one more record than what is required */
  210. retrievalInfo.setNoOfRecords(retrievalInfo.getNoOfRecords() + WebConstants.ONE);
  211. /*
  212. * Retrieve Project based on the retrieval information. If retrievalInfo
  213. * object is null then use default parameter information.
  214. */
  215. retrievalInfo = prepareRetrievalInfoForQuery(retrievalInfo);
  216. /* Prepare the Set of status */
  217. Set<String> statusOfProject = new HashSet<String>();
  218. statusOfProject.add(Project.STATUS_CREATED);
  219. return getProjectDao().getProjects(retrievalInfo, statusOfProject);
  220. }
  221. @Override
  222. public List<Project> listProjects(User user, RetrievalInfo retrievalInfo) {
  223. /*
  224. * Retrieve Project based on the retrieval information. If retrievalInfo
  225. * object is null then use default parameter information.
  226. */
  227. retrievalInfo = prepareRetrievalInfoForQuery(retrievalInfo);
  228. /* Prepare the Set of status */
  229. Set<String> statusOfProject = new HashSet<String>();
  230. statusOfProject.add(Project.STATUS_CREATED);
  231. return getProjectDao().getProjects(user, retrievalInfo, statusOfProject);
  232. }
  233. @Override
  234. public List<Project> getProjects(Set<String> projectKeys, RetrievalInfo retrievalInfo) {
  235. return getProjectDao().getProjectsByKeys(projectKeys, retrievalInfo);
  236. }
  237. /**
  238. * Prepares the {@link RetrievalInfo} object with values to be used as query
  239. * parameters.
  240. * Checks the received RetrievalInfo object attributes for valid
  241. * data.Updates the attributes if they contain garbage values.If the
  242. * received {@link RetrievalInfo} object is null,sets it to a new instance
  243. * with its attributes set to default values.
  244. *
  245. * @param retrievalInfo the {@link RetrievalInfo} object containing the
  246. * values to be used as query parameters
  247. * @return the {@link RetrievalInfo} object containing the query parameters
  248. */
  249. private RetrievalInfo prepareRetrievalInfoForQuery(RetrievalInfo retrievalInfo) {
  250. if (retrievalInfo == null) {
  251. retrievalInfo = new RetrievalInfo();
  252. retrievalInfo.setStartIndex(ServiceConstants.ZERO);
  253. retrievalInfo.setNoOfRecords(ServiceConstants.PROJECT_LIST_DEFAULT_SIZE);
  254. retrievalInfo.setOrderType(ServiceConstants.PROJECT_DEFAULT_ORDERING_TYPE);
  255. retrievalInfo.setOrderBy(ServiceConstants.DEFAULT_PROJECT_ORDERING_FIELD);
  256. } else {
  257. // Handle garbage values if any.
  258. String orderOn = retrievalInfo.getOrderBy();
  259. String orderByParam = retrievalInfo.getOrderType();
  260. if (retrievalInfo.getStartIndex() < ServiceConstants.ZERO)
  261. retrievalInfo.setStartIndex(ServiceConstants.ZERO);
  262. if (retrievalInfo.getNoOfRecords() <= ServiceConstants.ZERO)
  263. retrievalInfo.setNoOfRecords(ServiceConstants.PROJECT_LIST_DEFAULT_SIZE);
  264. if (orderByParam == null || !((orderByParam.equals(ServiceConstants.ORDERING_ASCENDING)
  265. || orderByParam.equals(ServiceConstants.ORDERING_DESCENDING))))
  266. retrievalInfo.setOrderType(ServiceConstants.PROJECT_DEFAULT_ORDERING_TYPE);
  267. if (orderOn == null
  268. || !orderOn.equals(ServiceConstants.PROJECT_ORDERING_FIELD_UPDATED_ON)) {
  269. retrievalInfo.setOrderBy(ServiceConstants.DEFAULT_PROJECT_ORDERING_FIELD);
  270. }
  271. }
  272. return retrievalInfo;
  273. }
  274. @Override
  275. public List<Project> getProjectsByIdeaKey(String key) {
  276. return getProjectDao().getProjectsByIdeaKey(key);
  277. }
  278. /**
  279. * @param ideaService the ideaService to set
  280. */
  281. public void setIdeaService(IdeaService ideaService) {
  282. this.ideaService = ideaService;
  283. }
  284. /**
  285. * @return the ideaService
  286. */
  287. public IdeaService getIdeaService() {
  288. return ideaService;
  289. }
  290. /**
  291. * @param projectDao the projectDao to set
  292. */
  293. public void setProjectDao(ProjectDao projectDao) {
  294. this.projectDao = projectDao;
  295. }
  296. /**
  297. * @return the projectDao
  298. */
  299. public ProjectDao getProjectDao() {
  300. return projectDao;
  301. }
  302. /**
  303. * @param auditManager the auditManager to set
  304. */
  305. public void setAuditManager(AuditManager auditManager) {
  306. this.auditManager = auditManager;
  307. }
  308. /**
  309. * @return the auditManager
  310. */
  311. public AuditManager getAuditManager() {
  312. return auditManager;
  313. }
  314. /**
  315. * @return the entityIndexService
  316. */
  317. public EntityIndexService getEntityIndexService() {
  318. return entityIndexService;
  319. }
  320. /**
  321. * @param entityIndexService the entityIndexService to set
  322. */
  323. public void setEntityIndexService(EntityIndexService entityIndexService) {
  324. this.entityIndexService = entityIndexService;
  325. }
  326. @Override
  327. public Project getProjectById(String key) {
  328. return projectDao.findEntityByPrimaryKey(Project.class, key);
  329. }
  330. @Override
  331. public List<Project> getRecentProjects() {
  332. RetrievalInfo retrievalInfo = new RetrievalInfo();
  333. retrievalInfo.setNoOfRecords(DEFAULT_NO_OF_RECENT_PROJECTS);
  334. retrievalInfo.setOrderBy(Project.PROJECT_FIELD_CREATED_ON);
  335. retrievalInfo.setOrderType(ServiceConstants.ORDERING_DESCENDING);
  336. /* The set of status to match for */
  337. Set<String> statusOfProject = new HashSet<String>();
  338. statusOfProject.add(Project.STATUS_CREATED);
  339. return projectDao.getProjects(retrievalInfo, statusOfProject);
  340. }
  341. @Override
  342. public Project updateProject(Project project) {
  343. return projectDao.saveProject(project);
  344. }
  345. }