001: package com.technoetic.xplanner.actions;
002:
003: import java.beans.BeanInfo;
004: import java.beans.IntrospectionException;
005: import java.beans.Introspector;
006: import java.beans.PropertyDescriptor;
007: import java.lang.reflect.InvocationTargetException;
008: import java.util.Collection;
009: import java.util.Iterator;
010: import javax.servlet.ServletException;
011: import javax.servlet.http.HttpServletRequest;
012: import javax.servlet.http.HttpServletResponse;
013:
014: import org.apache.log4j.Logger;
015: import org.apache.struts.action.ActionForm;
016: import org.apache.struts.action.ActionForward;
017: import org.apache.struts.action.ActionMapping;
018: import org.apache.struts.util.RequestUtils;
019:
020: import com.technoetic.xplanner.domain.DomainObject;
021: import com.technoetic.xplanner.domain.RelationshipConvertor;
022: import com.technoetic.xplanner.domain.RelationshipMappingRegistry;
023: import com.technoetic.xplanner.domain.repository.ObjectRepository;
024: import com.technoetic.xplanner.forms.AbstractEditorForm;
025: import com.technoetic.xplanner.util.LogUtil;
026:
027: public class EditObjectAction extends AbstractAction {
028: protected static final Logger log = LogUtil.getLogger();
029:
030: public static final String UPDATE_ACTION = "Update";
031: public static final String CREATE_ACTION = "Create";
032:
033: public static final String RETURNTO_PARAM = "returnto";
034: public static final String MERGE_PARAM = "merge";
035:
036: protected ActionForward doExecute(ActionMapping actionMapping,
037: ActionForm actionForm, HttpServletRequest request,
038: HttpServletResponse reply) throws Exception {
039: AbstractEditorForm form = (AbstractEditorForm) actionForm;
040: if (form.isSubmitted()) {
041: saveForm(form, actionMapping, request);
042: setCookies(form, actionMapping, request, reply);
043: String returnto = request.getParameter(RETURNTO_PARAM);
044: return returnto != null ? new ActionForward(returnto, true)
045: : actionMapping.findForward("view/projects");
046: } else {
047: populateForm(form, actionMapping, request);
048: return new ActionForward(actionMapping.getInput());
049: }
050: }
051:
052: protected void setCookies(AbstractEditorForm form,
053: ActionMapping mapping, HttpServletRequest request,
054: HttpServletResponse response) {
055: }
056:
057: protected void saveForm(AbstractEditorForm form,
058: ActionMapping actionMapping, HttpServletRequest request)
059: throws Exception {
060: String oid = form.getOid();
061: Class objectClass = getObjectType(actionMapping, request);
062: ObjectRepository objectRepository = getRepository(objectClass);
063: DomainObject object;
064: String action = form.getAction();
065: if (action.equals(UPDATE_ACTION)) {
066: object = updateObject(oid, request, form, objectRepository);
067: } else if (action.equals(CREATE_ACTION)) {
068: object = createObject(objectClass, request, form,
069: objectRepository);
070: } else {
071: throw new ServletException("Unknown editor action: "
072: + action);
073: }
074: setTargetObject(request, object);
075: form.setAction(null);
076: }
077:
078: protected DomainObject updateObject(String oid,
079: HttpServletRequest request, AbstractEditorForm form,
080: ObjectRepository objectRepository) throws Exception {
081: DomainObject object;
082: object = (DomainObject) objectRepository.load(Integer
083: .parseInt(oid));
084: populateObject(request, object, form);
085: objectRepository.update(object);
086: return object;
087: }
088:
089: protected DomainObject createObject(Class objectClass,
090: HttpServletRequest request, AbstractEditorForm form,
091: ObjectRepository objectRepository) throws Exception {
092: DomainObject object = (DomainObject) objectClass.newInstance();
093: populateObject(request, object, form);
094: int savedObjectId = objectRepository.insert(object);
095: form.setId(savedObjectId);
096: return object;
097: }
098:
099: protected void populateForm(AbstractEditorForm form,
100: ActionMapping actionMapping, HttpServletRequest request)
101: throws Exception {
102: String oid = form.getOid();
103: if (oid != null) {
104: Class objectClass = getObjectType(actionMapping, request);
105: ObjectRepository objectRepository = getRepository(objectClass);
106: DomainObject object = (DomainObject) objectRepository
107: .load(Integer.parseInt(oid));
108: populateForm(form, object);
109: }
110: }
111:
112: protected void populateForm(AbstractEditorForm form,
113: DomainObject object) throws Exception {
114: copyProperties(form, object);
115: populateManyToOneIds(form, object);
116: }
117:
118: private void copyProperties(Object destination, Object source)
119: throws Exception {
120: BeanInfo info = Introspector.getBeanInfo(source.getClass());
121: PropertyDescriptor[] properties = info.getPropertyDescriptors();
122: for (int i = 0; i < properties.length; i++) {
123: PropertyDescriptor sourceProperty = properties[i];
124: PropertyDescriptor destinationProperty = findProperty(
125: destination, sourceProperty.getName());
126: if (destinationProperty != null
127: && destinationProperty.getWriteMethod() != null
128: && sourceProperty.getReadMethod() != null) {
129: Object value = sourceProperty.getReadMethod().invoke(
130: source, new Object[0]);
131: log.debug(" " + destinationProperty.getName() + "="
132: + value);
133: destinationProperty.getWriteMethod().invoke(
134: destination, new Object[] { value });
135: }
136: }
137: }
138:
139: private PropertyDescriptor findProperty(Object object, String name)
140: throws IntrospectionException {
141: BeanInfo info = Introspector.getBeanInfo(object.getClass());
142: PropertyDescriptor[] properties = info.getPropertyDescriptors();
143: for (int i = 0; i < properties.length; i++) {
144: PropertyDescriptor property = properties[i];
145: if (property.getName().equals(name)) {
146: return property;
147: }
148: }
149: return null;
150: }
151:
152: protected void populateManyToOneIds(ActionForm form,
153: DomainObject object) throws IllegalAccessException,
154: NoSuchMethodException, InvocationTargetException {
155: Collection mappings = RelationshipMappingRegistry.getInstance()
156: .getRelationshipMappings(object);
157: for (Iterator iterator = mappings.iterator(); iterator
158: .hasNext();) {
159: RelationshipConvertor convertor = (RelationshipConvertor) iterator
160: .next();
161: convertor.populateAdapter(form, object);
162: }
163: }
164:
165: protected void populateObject(HttpServletRequest request,
166: Object object, ActionForm form) throws Exception {
167: log.debug("Populating object " + object.getClass().getName()
168: + " " + ((DomainObject) object).getId());
169: if ("true".equals(request.getParameter(MERGE_PARAM))) {
170: RequestUtils.populate(object, request);
171: //TODO: should we populate many-to-one rels in this mode?
172: } else {
173: copyProperties(object, form);
174: populateManyToOneRelationships((DomainObject) object, form);
175: }
176: }
177:
178: protected void populateManyToOneRelationships(DomainObject object,
179: ActionForm form) throws Exception {
180: Collection mappings = RelationshipMappingRegistry.getInstance()
181: .getRelationshipMappings(object);
182: for (Iterator iterator = mappings.iterator(); iterator
183: .hasNext();) {
184: RelationshipConvertor convertor = (RelationshipConvertor) iterator
185: .next();
186: convertor.populateDomainObject(object, form);
187: }
188: }
189: }
|