PageRenderTime 39ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/crank-crud/src/main/java/org/crank/crud/controller/CrudControllerBase.java

http://krank.googlecode.com/
Java | 573 lines | 433 code | 83 blank | 57 comment | 52 complexity | c9c9930b5bda19c182850b99227746f4 MD5 | raw file
  1. package org.crank.crud.controller;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import org.apache.log4j.Logger;
  8. import org.crank.annotations.design.AllowsConfigurationInjection;
  9. import org.crank.annotations.design.ExpectsInjection;
  10. import org.crank.annotations.design.OptionalInjection;
  11. import org.crank.core.CrankValidationException;
  12. import org.crank.core.PropertiesUtil;
  13. import org.crank.core.RequestParameterMapFinder;
  14. import org.crank.core.spring.support.SpringBeanWrapperPropertiesUtil;
  15. import org.crank.crud.GenericDao;
  16. import org.crank.message.MessageManagerUtils;
  17. import org.crank.message.MessageUtils;
  18. import org.crank.web.RequestParameterMapFinderImpl;
  19. //import org.springframework.transaction.annotation.Transactional;
  20. /**
  21. *
  22. * @author Rick Hightower, Tom Cellucci
  23. *
  24. * @param <T>
  25. * Entity type
  26. * @param <PK>
  27. * primary key type
  28. *
  29. * Please note that some methods are marked transactional but are not unless
  30. * this gets proxied.
  31. */
  32. public abstract class CrudControllerBase<T extends Serializable, PK extends Serializable>
  33. implements CrudOperations<T>, Serializable {
  34. protected Logger logger = Logger.getLogger(CrudControllerBase.class);
  35. /* The DAO we use to persist T objects to the databasae. */
  36. protected GenericDao<T, PK> dao;
  37. protected EntityLocator<T> entityLocator;
  38. protected PropertiesUtil propertyUtil = new SpringBeanWrapperPropertiesUtil();
  39. protected String idPropertyName = "id";
  40. protected boolean readPopulated = true;
  41. protected Class<T> entityClass;
  42. protected CrudState state;
  43. protected T entity;
  44. private Map<String, DetailController<? extends Serializable, ? extends Serializable>> children = new HashMap<String, DetailController<? extends Serializable, ? extends Serializable>>();
  45. private ToggleSupport toggleSupport = new ToggleSupport();
  46. private String name;
  47. protected CrudOperations<?> parent;
  48. protected RequestParameterMapFinder requestParameterMapFinder = new RequestParameterMapFinderImpl();
  49. protected Map<String, Object> dynamicProperties = new CrankMap();
  50. protected FileUploadHandler fileUploadHandler;
  51. protected String idParam = "id";
  52. protected String deleteStrategy = CrudOperations.DELETE_BY_ENTITY;
  53. protected String addStrategy = CrudOperations.ADD_BY_CREATE;
  54. protected boolean transactional = false;
  55. protected boolean suppressStatusMessages = false;
  56. public boolean isSuppressStatusMessages() {
  57. return suppressStatusMessages;
  58. }
  59. public void setSuppressStatusMessages(boolean suppressStatusMessages) {
  60. this.suppressStatusMessages = suppressStatusMessages;
  61. }
  62. public boolean isTransactional() {
  63. return transactional;
  64. }
  65. public void setTransactional(boolean transactional) {
  66. this.transactional = transactional;
  67. }
  68. public CrudControllerBase() {
  69. super();
  70. }
  71. public String getName() {
  72. return name != null ? name : CrudUtils.getClassEntityName(entityClass);
  73. }
  74. public String getNameUpperCase() {
  75. return getName().toUpperCase();
  76. }
  77. public String getNamePlural() {
  78. String name = getName();
  79. if (name.endsWith("s")) {
  80. return name + "es";
  81. } else {
  82. return name + "s";
  83. }
  84. }
  85. public String getNamePluralAndUpperCase() {
  86. return getNamePlural().toUpperCase();
  87. }
  88. public void setName(String name) {
  89. this.name = name;
  90. }
  91. /**
  92. * @see Toggleable#addToggleListener(ToggleListener)
  93. */
  94. public void addToggleListener(ToggleListener listener) {
  95. toggleSupport.addToggleListener(listener);
  96. }
  97. /**
  98. * @see Toggleable#addToggleListener(ToggleListener)
  99. */
  100. public void removeToggleListener(ToggleListener listener) {
  101. toggleSupport.removeToggleListener(listener);
  102. }
  103. /**
  104. * Fire an event to the Toggle listeners.
  105. *
  106. */
  107. protected void fireToggle() {
  108. toggleSupport.fireToggle();
  109. }
  110. /**
  111. * @see CrudOperations#getEntity()
  112. */
  113. public T getEntity() {
  114. return entity;
  115. }
  116. public void setDao(GenericDao<T, PK> dao) {
  117. this.dao = dao;
  118. }
  119. @ExpectsInjection
  120. public void setPropertyUtil(PropertiesUtil propertyUtil) {
  121. this.propertyUtil = propertyUtil;
  122. }
  123. @OptionalInjection
  124. public void setIdPropertyName(String idPropertyName) {
  125. this.idPropertyName = idPropertyName;
  126. }
  127. @AllowsConfigurationInjection
  128. public void setReadPopulated(boolean readPopulated) {
  129. this.readPopulated = readPopulated;
  130. }
  131. @AllowsConfigurationInjection
  132. public void setEntityClass(Class<T> entityClass) {
  133. this.entityClass = entityClass;
  134. }
  135. public Class<T> getEntityClass() {
  136. return entityClass;
  137. }
  138. public CrudState getState() {
  139. return state;
  140. }
  141. public Map<String, DetailController<? extends Serializable, ? extends Serializable>> getChildren() {
  142. return children;
  143. }
  144. public void setChildren(
  145. Map<String, DetailController<? extends Serializable, ? extends Serializable>> children) {
  146. this.children = children;
  147. }
  148. public void init() {
  149. logger.debug("init called setting CrudState to UNKNOWN");
  150. this.state = CrudState.UNKNOWN;
  151. initDetailChildren();
  152. parentChildren();
  153. }
  154. private void initDetailChildren() {
  155. if (children != null) {
  156. for (CrudControllerBase<? extends Serializable, ? extends Serializable> detailController : children
  157. .values()) {
  158. logger.debug(String.format("initializing child %s %s", detailController.getName(), detailController));
  159. detailController.init();
  160. }
  161. }
  162. }
  163. /**
  164. * Inject this parent into all Children. It's fathers day. Give all the
  165. * children a daddy.
  166. */
  167. private void parentChildren() {
  168. if (children != null) {
  169. for (CrudControllerBase<? extends Serializable, ? extends Serializable> detailController : children
  170. .values()) {
  171. detailController.setParent(this);
  172. }
  173. }
  174. }
  175. /**
  176. * Call cancelSubForms on all children.
  177. *
  178. */
  179. protected void cancelChildren() {
  180. if (children != null) {
  181. for (CrudControllerBase<? extends Serializable, ? extends Serializable> detailController : children
  182. .values()) {
  183. detailController.cancel();
  184. }
  185. }
  186. }
  187. public <CE extends Serializable, CEPK extends Serializable> CrudControllerBase<CE, CEPK> addChild(
  188. String name, DetailController<CE, CEPK> detailController) {
  189. this.children.put(name, detailController);
  190. if (detailController.getRelationshipManager()
  191. .getChildCollectionProperty() == null) {
  192. detailController.getRelationshipManager()
  193. .setChildCollectionProperty(name);
  194. }
  195. detailController.setParent(this);
  196. return detailController;
  197. }
  198. /**
  199. * Create a new entity. An Entity is the object we are managing.
  200. *
  201. */
  202. protected void createEntity() {
  203. logger.debug("Calling createEntity");
  204. try {
  205. this.entity = entityClass.newInstance();
  206. logger.debug(String.format("Entity created", this.entity));
  207. } catch (Exception ex) {
  208. logger.error("Unable to create entity",ex);
  209. throw new RuntimeException(ex);
  210. }
  211. }
  212. public CrudOperations<?> getParent() {
  213. return parent;
  214. }
  215. public void setParent(CrudOperations<?> parent) {
  216. this.parent = parent;
  217. }
  218. public boolean isShowListing() {
  219. return state != CrudState.ADD || state != CrudState.EDIT;
  220. }
  221. public boolean isShowForm() {
  222. return state == CrudState.ADD || state == CrudState.EDIT;
  223. }
  224. public void setRequestParameterMapFinder(
  225. RequestParameterMapFinder requestParameterMapFinder) {
  226. this.requestParameterMapFinder = requestParameterMapFinder;
  227. }
  228. public Map<String, Object> getDynamicProperties() {
  229. return dynamicProperties;
  230. }
  231. public void setDynamicProperties(Map<String, Object> dynamicProperties) {
  232. this.dynamicProperties = dynamicProperties;
  233. }
  234. public void setFileUploadHandler(FileUploadHandler fileUploadHandler) {
  235. this.fileUploadHandler = fileUploadHandler;
  236. }
  237. /** Create an object. */
  238. //@Transactional
  239. public CrudOutcome create() {
  240. if (fileUploadHandler != null) {
  241. fileUploadHandler.upload(this);
  242. }
  243. try {
  244. logger.debug("before create");
  245. fireBeforeCreate();
  246. CrudOutcome outcome = doCreate();
  247. if (!suppressStatusMessages) {
  248. MessageManagerUtils.getCurrentInstance().addStatusMessage(
  249. "Created %s", MessageUtils.createLabel(this.getName()));
  250. }
  251. logger.debug("create");
  252. fireAfterCreate();
  253. logger.debug("create after event handling");
  254. return outcome;
  255. } catch (CrankValidationException ex) {
  256. if (transactional == true) {
  257. throw ex;
  258. }
  259. }
  260. return null;
  261. }
  262. /** Load create an object. */
  263. public CrudOutcome loadCreate() {
  264. try {
  265. logger.debug("loadCreate called");
  266. fireBeforeLoadCreate();
  267. CrudOutcome outcome = doLoadCreate();
  268. fireAfterLoadCreate();
  269. return outcome;
  270. } catch (CrankValidationException e) {
  271. e.printStackTrace();
  272. }
  273. return null;
  274. }
  275. /** Update an object. */
  276. //@Transactional
  277. public CrudOutcome update() {
  278. if (fileUploadHandler != null) {
  279. fileUploadHandler.upload(this);
  280. }
  281. try {
  282. logger.debug("before update");
  283. fireBeforeUpdate();
  284. CrudOutcome outcome = doUpdate();
  285. if (!suppressStatusMessages) {
  286. MessageManagerUtils.getCurrentInstance().addStatusMessage(
  287. "Updated %s", MessageUtils.createLabel(this.getName()));
  288. }
  289. logger.debug("update");
  290. fireAfterUpdate();
  291. logger.debug("after event handling");
  292. return outcome;
  293. } catch (CrankValidationException ex) {
  294. if (transactional == true) {
  295. throw ex;
  296. }
  297. }
  298. return null;
  299. }
  300. /** Update an object. */
  301. //@Transactional
  302. public CrudOutcome delete() {
  303. logger.debug("delete");
  304. fireBeforeDelete(this.entity);
  305. CrudOutcome outcome = doDelete();
  306. if (!suppressStatusMessages) {
  307. MessageManagerUtils.getCurrentInstance().addStatusMessage("Deleted %s",
  308. MessageUtils.createLabel(this.getName()));
  309. }
  310. fireAfterDelete(this.entity);
  311. return outcome;
  312. }
  313. /** Update an object. */
  314. //@Transactional
  315. public CrudOutcome read() {
  316. fireBeforeRead();
  317. CrudOutcome outcome = doRead();
  318. fireAfterRead();
  319. return outcome;
  320. }
  321. /** Load Listing. */
  322. public CrudOutcome loadListing() {
  323. fireBeforeLoadListing();
  324. CrudOutcome outcome = doLoadListing();
  325. fireAfterLoadListing();
  326. return outcome;
  327. }
  328. /** Update an object. */
  329. public CrudOutcome cancel() {
  330. fireBeforeCancel();
  331. CrudOutcome outcome = doCancel();
  332. fireAfterCancel();
  333. return outcome;
  334. }
  335. protected abstract CrudOutcome doCancel();
  336. /** Create an object. */
  337. protected abstract CrudOutcome doCreate();
  338. /** Update an object. */
  339. protected abstract CrudOutcome doUpdate();
  340. /** Delete an object. */
  341. protected abstract CrudOutcome doDelete();
  342. /** Read an object. */
  343. protected abstract CrudOutcome doRead();
  344. /** Read an object. */
  345. protected abstract CrudOutcome doLoadCreate();
  346. /** Read an object. */
  347. protected abstract CrudOutcome doLoadListing();
  348. protected String retrieveId() {
  349. String[] params = this.requestParameterMapFinder.getMap().get(
  350. this.idParam);
  351. if (params != null && params.length > 0) {
  352. return params[0];
  353. } else {
  354. return null;
  355. }
  356. }
  357. private List<CrudControllerListener> listeners = new ArrayList<CrudControllerListener>();
  358. public void addCrudControllerListener(CrudControllerListener listener) {
  359. listeners.add(listener);
  360. }
  361. public void removeCrudControllerListener(CrudControllerListener listener) {
  362. listeners.remove(listener);
  363. }
  364. protected void fireAfterUpdate() {
  365. CrudEvent event = new CrudEvent(this, this.entity);
  366. for (CrudControllerListener ccl : listeners) {
  367. ccl.afterUpdate(event);
  368. }
  369. }
  370. protected void fireBeforeUpdate() {
  371. CrudEvent event = new CrudEvent(this, this.entity);
  372. for (CrudControllerListener ccl : listeners) {
  373. ccl.beforeUpdate(event);
  374. }
  375. }
  376. protected void fireBeforeCreate() {
  377. CrudEvent event = new CrudEvent(this, this.entity);
  378. for (CrudControllerListener ccl : listeners) {
  379. ccl.beforeCreate(event);
  380. }
  381. }
  382. protected void fireAfterCreate() {
  383. CrudEvent event = new CrudEvent(this, this.entity);
  384. for (CrudControllerListener ccl : listeners) {
  385. ccl.afterCreate(event);
  386. }
  387. }
  388. protected void fireBeforeLoadCreate() {
  389. CrudEvent event = new CrudEvent(this, this.entity);
  390. for (CrudControllerListener ccl : listeners) {
  391. ccl.beforeLoadCreate(event);
  392. }
  393. }
  394. protected void fireAfterLoadCreate() {
  395. CrudEvent event = new CrudEvent(this, this.entity);
  396. for (CrudControllerListener ccl : listeners) {
  397. ccl.afterLoadCreate(event);
  398. }
  399. }
  400. protected void fireBeforeRead() {
  401. CrudEvent event = new CrudEvent(this, this.entity);
  402. for (CrudControllerListener ccl : listeners) {
  403. ccl.beforeRead(event);
  404. }
  405. }
  406. protected void fireAfterRead() {
  407. CrudEvent event = new CrudEvent(this, this.entity);
  408. for (CrudControllerListener ccl : listeners) {
  409. ccl.afterRead(event);
  410. }
  411. }
  412. protected void fireBeforeDelete(T beforeDeleteEntity) {
  413. CrudEvent event = new CrudEvent(this, beforeDeleteEntity);
  414. for (CrudControllerListener ccl : listeners) {
  415. ccl.beforeDelete(event);
  416. }
  417. }
  418. protected void fireAfterDelete(T afterDeleteEntity) {
  419. CrudEvent event = new CrudEvent(this, afterDeleteEntity);
  420. for (CrudControllerListener ccl : listeners) {
  421. ccl.afterDelete(event);
  422. }
  423. }
  424. protected void fireBeforeCancel() {
  425. CrudEvent event = new CrudEvent(this, this.entity);
  426. for (CrudControllerListener ccl : listeners) {
  427. ccl.beforeCancel(event);
  428. }
  429. }
  430. protected void fireAfterCancel() {
  431. CrudEvent event = new CrudEvent(this, this.entity);
  432. for (CrudControllerListener ccl : listeners) {
  433. ccl.afterCancel(event);
  434. }
  435. }
  436. private void fireAfterLoadListing() {
  437. CrudEvent event = new CrudEvent(this, this.entity);
  438. for (CrudControllerListener ccl : listeners) {
  439. ccl.afterLoadListing(event);
  440. }
  441. }
  442. private void fireBeforeLoadListing() {
  443. CrudEvent event = new CrudEvent(this, this.entity);
  444. for (CrudControllerListener ccl : listeners) {
  445. ccl.beforeLoadListing(event);
  446. }
  447. }
  448. public String getDeleteStrategy() {
  449. return deleteStrategy;
  450. }
  451. public void setDeleteStrategy(String deleteStrategy) {
  452. this.deleteStrategy = deleteStrategy;
  453. }
  454. public String getAddStrategy() {
  455. return addStrategy;
  456. }
  457. public void setAddStrategy(String addStrategy) {
  458. this.addStrategy = addStrategy;
  459. }
  460. public CrudOutcome deleteSelected() {
  461. List<T> listToDelete = getSelectedEntities();
  462. /* You could change this to delete a list of ids. */
  463. for (T entity : listToDelete) {
  464. fireBeforeDelete(entity);
  465. doDelete(entity);
  466. fireToggle();
  467. fireAfterDelete(entity);
  468. }
  469. MessageManagerUtils.getCurrentInstance().addStatusMessage("Deleted selections");
  470. return null;
  471. }
  472. protected List<T> getSelectedEntities() {
  473. return entityLocator.getSelectedEntities();
  474. }
  475. @ExpectsInjection
  476. public void setEntityLocator(EntityLocator<T> entityLocator) {
  477. this.entityLocator = entityLocator;
  478. }
  479. @SuppressWarnings("unchecked")
  480. protected void doDelete(T entity) {
  481. if (deleteStrategy.equals(CrudOperations.DELETE_BY_ENTITY)) {
  482. entity = dao.read((PK) propertyUtil.getPropertyValue(
  483. idPropertyName, entity));
  484. dao.delete((T) entity);
  485. } else {
  486. dao.delete((PK) propertyUtil.getPropertyValue(idPropertyName,
  487. entity));
  488. }
  489. }
  490. }