001: package com.technoetic.xplanner.actions;
002:
003: import javax.servlet.ServletException;
004: import javax.servlet.http.HttpServletRequest;
005: import javax.servlet.http.HttpServletResponse;
006:
007: import net.sf.hibernate.Session;
008: import org.apache.commons.lang.StringUtils;
009: import org.apache.log4j.Logger;
010: import org.apache.struts.Globals;
011: import org.apache.struts.action.Action;
012: import org.apache.struts.action.ActionError;
013: import org.apache.struts.action.ActionErrors;
014: import org.apache.struts.action.ActionForm;
015: import org.apache.struts.action.ActionForward;
016: import org.apache.struts.action.ActionMapping;
017:
018: import com.technoetic.xplanner.db.hibernate.HibernateHelper;
019: import com.technoetic.xplanner.db.hibernate.ThreadSession;
020: import com.technoetic.xplanner.domain.Iteration;
021: import com.technoetic.xplanner.domain.Project;
022: import com.technoetic.xplanner.domain.repository.MetaRepository;
023: import com.technoetic.xplanner.domain.repository.ObjectRepository;
024: import com.technoetic.xplanner.domain.repository.RepositoryException;
025: import com.technoetic.xplanner.tags.DomainContext;
026: import com.technoetic.xplanner.tx.CheckedExceptionHandlingTransactionTemplate;
027: import com.technoetic.xplanner.util.Callable;
028: import com.technoetic.xplanner.util.LogUtil;
029: import com.technoetic.xplanner.util.RequestUtils;
030:
031: public abstract class AbstractAction extends Action {
032: static Logger LOG = LogUtil.getLogger();
033:
034: public static final String TYPE_KEY = "@type";
035: private static final String TARGET_OBJECT = "targetObject";
036: private String type;
037: private MetaRepository metaRepository;
038: protected CheckedExceptionHandlingTransactionTemplate transactionTemplate;
039:
040: public ActionForward execute(final ActionMapping mapping,
041: final ActionForm form, final HttpServletRequest request,
042: final HttpServletResponse response) throws Exception {
043: if (LOG.isDebugEnabled()) {
044: String name = mapping.getName();
045: String requestParams = RequestUtils.toString(request);
046: String action = "\naction=\"" + name + "\" requestParams="
047: + requestParams;
048: LOG.debug(action);
049: }
050: try {
051: ActionForward forward = (ActionForward) transactionTemplate
052: .execute(new Callable() {
053: public Object run() throws Exception {
054: ActionForward forward = doExecute(mapping,
055: form, request, response);
056: // DEBT JM DEBT: Should be a instance member. Try converting to SpringAction to have a stateful action with members
057: Object object = getTargetObject(request);
058: if (object != null) {
059: beforeObjectCommit(object,
060: ThreadSession.get(), mapping,
061: form, request, response);
062: }
063: return forward;
064:
065: }
066: });
067: afterObjectCommit(mapping, form, request, response);
068: return forward;
069: } catch (Throwable e) {
070: LOG.error(e);
071: if (e instanceof RuntimeException)
072: throw (RuntimeException) e;
073: if (e instanceof Error)
074: throw (Error) e;
075: if (e instanceof Exception)
076: throw (Exception) e;
077: return null; //never reached
078: }
079: }
080:
081: //DEBT(SPRING) Remove access to session. Access to the db should always go through repositories or queries that are injected
082: protected void beforeObjectCommit(Object object, Session session,
083: ActionMapping actionMapping, ActionForm actionForm,
084: HttpServletRequest request, HttpServletResponse reply)
085: throws Exception {
086: }
087:
088: protected void afterObjectCommit(ActionMapping actionMapping,
089: ActionForm actionForm, HttpServletRequest request,
090: HttpServletResponse reply) throws Exception {
091: }
092:
093: protected abstract ActionForward doExecute(ActionMapping mapping,
094: ActionForm form, HttpServletRequest request,
095: HttpServletResponse response) throws Exception;
096:
097: protected Class getObjectType(ActionMapping actionMapping,
098: HttpServletRequest request) throws ClassNotFoundException,
099: ServletException {
100: String className = type;
101: if (className == null) {
102: className = getObjectTypeFromForward(actionMapping,
103: className);
104: }
105: if (className == null) {
106: className = request.getParameter(TYPE_KEY);
107: }
108: if (className != null) {
109: return Class.forName(className);
110: } else {
111: throw new ServletException(
112: "no object type is specified in mapping or request");
113: }
114: }
115:
116: private String getObjectTypeFromForward(
117: ActionMapping actionMapping, String className) {
118: ActionForward forward = actionMapping.findForward(TYPE_KEY);
119: if (forward != null) {
120: className = forward.getPath();
121: }
122: return className;
123: }
124:
125: protected DomainContext setDomainContext(
126: HttpServletRequest request, Object object,
127: ActionMapping actionMapping) throws Exception {
128: DomainContext domainContext = DomainContext.get(request);
129: if (domainContext != null) {
130: return domainContext;
131: }
132: domainContext = new DomainContext();
133: domainContext.populate(object);
134: domainContext.setActionMapping(actionMapping);
135: String projectIdParam = request.getParameter("projectId");
136: if (domainContext.getProjectId() == 0
137: && StringUtils.isNotEmpty(projectIdParam)
138: && !projectIdParam.equals("0")) {
139: ObjectRepository objectRepository = getRepository(Project.class);
140: Project project = (Project) objectRepository.load(Integer
141: .parseInt((request.getParameter("projectId"))));
142: domainContext.populate(project);
143: }
144: domainContext.save(request);
145: return domainContext;
146: }
147:
148: public void addError(HttpServletRequest request, String errorKey) {
149: addError(request, new ActionError(errorKey));
150: }
151:
152: public void addError(HttpServletRequest request, String errorKey,
153: Object arg) {
154: addError(request, new ActionError(errorKey, arg));
155: }
156:
157: private void addError(HttpServletRequest request, ActionError error) {
158: ActionErrors errors = getActionErrors(request);
159: errors.add(ActionErrors.GLOBAL_ERROR, error);
160: }
161:
162: private ActionErrors getActionErrors(HttpServletRequest request) {
163: ActionErrors errors = (ActionErrors) request
164: .getAttribute(Globals.ERROR_KEY);
165: if (errors == null) {
166: errors = new ActionErrors();
167: request.setAttribute(Globals.ERROR_KEY, errors);
168: }
169: return errors;
170: }
171:
172: public ActionForward getGeneralErrorForward(ActionMapping mapping,
173: HttpServletRequest request, String errorKey) {
174: addError(request, errorKey);
175: return mapping.findForward("error");
176: }
177:
178: public ActionForward getGeneralErrorForward(ActionMapping mapping,
179: HttpServletRequest request, String errorKey, Object arg) {
180: addError(request, errorKey, arg);
181: return mapping.findForward("error");
182:
183: }
184:
185: protected Object getTargetObject(HttpServletRequest request) {
186: return request.getAttribute(TARGET_OBJECT);
187: }
188:
189: protected void setTargetObject(HttpServletRequest request,
190: Object target) {
191: request.setAttribute(TARGET_OBJECT, target);
192: }
193:
194: protected Session getSession(HttpServletRequest request) {
195: return HibernateHelper.getSession(request);
196: }
197:
198: public void setType(String type) {
199: this .type = type;
200: }
201:
202: public void setMetaRepository(MetaRepository metaRepository) {
203: this .metaRepository = metaRepository;
204: }
205:
206: public MetaRepository getMetaRepository() {
207: return metaRepository;
208: }
209:
210: public ObjectRepository getRepository(Class objectClass) {
211: return getMetaRepository().getRepository(objectClass);
212: }
213:
214: public void setTransactionTemplate(
215: CheckedExceptionHandlingTransactionTemplate transactionTemplate) {
216: this .transactionTemplate = transactionTemplate;
217: }
218:
219: public Iteration getIteration(int id) throws RepositoryException {
220: return (Iteration) getRepository(Iteration.class).load(id);
221: }
222:
223: }
|