Java tutorial
/** * * APDPlat - Application Product Development Platform * Copyright (c) 2013, ??, yang-shangchuan@qq.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.apdplat.platform.action; import org.apdplat.module.security.model.User; import org.apdplat.module.system.service.ExcelService; import org.apdplat.platform.action.converter.DateTypeConverter; import org.apdplat.platform.annotation.ModelAttr; import org.apdplat.platform.annotation.ModelAttrRef; import org.apdplat.platform.annotation.ModelCollRef; import org.apdplat.platform.annotation.RenderIgnore; import org.apdplat.platform.criteria.Property; import org.apdplat.platform.model.Model; import org.apdplat.platform.result.Page; import org.apdplat.platform.util.ReflectionUtils; import org.apdplat.platform.util.SpringContextUtils; import org.apdplat.platform.util.Struts2Utils; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.OneToOne; import javax.persistence.Temporal; import org.apache.commons.lang.StringUtils; import org.apdplat.platform.annotation.RenderDate; import org.apdplat.platform.annotation.RenderTime; /** * *? *?EXT JS * @author ?? */ public abstract class ExtJSSimpleAction<T extends Model> extends ExtJSActionSupport implements Action { private boolean search = false; protected T model = null; protected Class<T> modelClass; protected Page<T> page = new Page<>(); @Resource(name = "springContextUtils") protected SpringContextUtils springContextUtils; @Resource(name = "excelService") protected ExcelService excelService; protected Map map = null; @PostConstruct private void initModel() { try { if (this.model == null) { String modelName = getDefaultModelName(); if ("model".equals(modelName)) { this.model = (T) getRequest().getAttribute("model"); } else { this.model = (T) springContextUtils.getBean(modelName); } modelClass = (Class<T>) model.getClass(); } } catch (Exception e) { LOG.error("initModel fail"); } } public String report() { return null; } public String chart() { if (StringUtils.isNotBlank(getQueryString())) { //?? beforeSearch(); page = getService().search(getQueryString(), null, modelClass); List<T> models = processSearchResult(page.getModels()); page.setModels(models); } else { beforeQuery(); this.setPage(getService().query(modelClass)); } //?XML? String data = generateReportData(page.getModels()); if (StringUtils.isBlank(data)) { LOG.info("??"); return null; } Struts2Utils.renderXml(data); //???? this.getPage().getModels().clear(); this.setPage(null); return null; } protected String generateReportData(List<T> models) { return null; } private String getDefaultModelName() { return getDefaultModelName(this.getClass()); } @Override protected User refreshUser(User user) { return getService().retrieve(User.class, user.getId()); } @Override public String create() { try { try { checkModel(model); } catch (Exception e) { map = new HashMap(); map.put("success", false); map.put("message", e.getMessage() + ",?"); Struts2Utils.renderJson(map); return null; } assemblyModelForCreate(model); objectReference(model); getService().create(model); afterSuccessCreateModel(model); } catch (Exception e) { LOG.error("", e); afterFailCreateModel(model); map = new HashMap(); map.put("success", false); map.put("message", " " + e.getMessage()); Struts2Utils.renderJson(map); return null; } map = new HashMap(); map.put("success", true); map.put("message", "?"); Struts2Utils.renderJson(map); return null; } @Override public String createForm() { return FORM; } @Override public String retrieve() { this.setModel(getService().retrieve(modelClass, model.getId())); if (model == null) { Struts2Utils.renderText("false"); return null; } afterRetrieve(model); Map temp = new HashMap(); renderJsonForRetrieve(temp); retrieveAfterRender(temp, model); Struts2Utils.renderJson(temp); return null; } protected void afterRetrieve(T model) { } @Override public String updateForm() { setModel(getService().retrieve(modelClass, model.getId())); return null; } @Override public String updatePart() { try { Integer version = model.getVersion(); //model??? List<Property> properties = getPartProperties(model); //model??? model = getService().retrieve(modelClass, model.getId()); //????? if (version == null) { LOG.info("????"); throw new RuntimeException("??"); } else { LOG.info("????,version=" + version); } if (version != model.getVersion()) { LOG.info("?? " + model.getVersion() + ", " + version); throw new RuntimeException("??"); } old(model); for (Property property : properties) { //??model if (property.getName().contains(".")) { //?model.org.id=1 if (property.getName().contains(".id")) { String[] attr = property.getName().replace(".", ",").split(","); if (attr.length == 2) { Field field = ReflectionUtils.getDeclaredField(model, attr[0]); T change = getService().retrieve((Class<T>) field.getType(), (Integer) property.getValue()); ReflectionUtils.setFieldValue(model, attr[0], change); } } } else { ReflectionUtils.setFieldValue(model, property.getName(), property.getValue()); } } now(model); //??? assemblyModelForUpdate(model); getService().update(model); afterSuccessPartUpdateModel(model); } catch (Exception e) { LOG.error("", e); afterFailPartUpdateModel(model); map = new HashMap(); map.put("success", false); map.put("message", " " + e.getMessage()); Struts2Utils.renderJson(map); return null; } map = new HashMap(); map.put("success", true); map.put("message", "?"); Struts2Utils.renderJson(map); return null; } @Override public String updateWhole() { try { assemblyModelForUpdate(model); getService().update(model); afterSuccessWholeUpdateModel(model); } catch (Exception e) { LOG.error("", e); afterFailWholeUpdateModel(model); Struts2Utils.renderText("false"); return null; } Struts2Utils.renderText("true"); return null; } public void prepareForDelete(Integer[] ids) { } public String deleteSession() { return null; } @Override public String delete() { try { prepareForDelete(getIds()); List<Integer> deletedIds = getService().delete(modelClass, getIds()); afterDelete(deletedIds); } catch (Exception e) { LOG.info("?", e); Struts2Utils.renderText(e.getMessage()); return null; } Struts2Utils.renderText("?"); return null; } public void afterDelete(List<Integer> deletedIds) { } @Override public String query() { beforeQuery(); if (search) { search(); return null; } this.setPage( getService().query(modelClass, getPageCriteria(), buildPropertyCriteria(), buildOrderCriteria())); Map json = new HashMap(); json.put("totalProperty", page.getTotalRecords()); List<Map> result = new ArrayList<>(); renderJsonForQuery(result); json.put("root", result); Struts2Utils.renderJson(json); //???? this.getPage().getModels().clear(); this.setPage(null); return null; } public String export() { if (search) { //? page = getService().search(getQueryString(), null, modelClass); List<T> models = processSearchResult(page.getModels()); page.setModels(models); //?? //this.setPage(getService().search(getQueryString(), getPageCriteria(), modelClass)); } else { //? this.setPage(getService().query(modelClass, null, buildPropertyCriteria(), buildOrderCriteria())); //?? //this.setPage(getService().query(modelClass, getPageCriteria(), buildPropertyCriteria(), buildOrderCriteria())); } List<List<String>> result = new ArrayList<>(); renderForExport(result); String path = excelService.write(result, exportFileName()); Struts2Utils.renderText(path); //???? this.getPage().getModels().clear(); this.setPage(null); return null; } private List<T> processSearchResult(List<T> models) { List<T> result = new ArrayList<>(); for (T obj : models) { T t = getService().retrieve(modelClass, obj.getId()); if (t != null) { result.add(t); } } return result; } @Override public String search() { beforeSearch(); page = getService().search(getQueryString(), getPageCriteria(), modelClass); //List<T> models=processSearchResult(page.getModels()); //page.setModels(models); Map json = new HashMap(); json.put("totalProperty", page.getTotalRecords()); List<Map> result = new ArrayList<>(); renderJsonForSearch(result); json.put("root", result); Struts2Utils.renderJson(json); return null; } protected void beforeQuery() { } protected void beforeSearch() { } protected void checkModel(T model) throws Exception { } /** * ??Model?Model??Model * @return */ protected void assemblyModelForCreate(T model) { } protected void assemblyModelForUpdate(T model) { } /** * ???? * @return */ protected void afterSuccessPartUpdateModel(T model) { } protected void old(T model) { } protected void now(T model) { } /** * ??? * @return */ protected void afterFailPartUpdateModel(T model) { } /** * ???? * @return */ protected void afterSuccessWholeUpdateModel(T model) { } /** * ??? * @return */ protected void afterFailWholeUpdateModel(T model) { } /** * ??? * @return */ protected void afterSuccessCreateModel(T model) { } /** * ?? * @return */ protected void afterFailCreateModel(T model) { } /////////////////////////////////////?Action??Action? /** * ???? * @return */ protected void renderJsonForRetrieve(Map map) { render(map, model); } /** * ???? * @return */ protected void renderJsonForSearch(List result) { renderJsonForQuery(result); } /** * ??? * @return */ protected void renderJsonForQuery(List result) { for (T obj : page.getModels()) { Map temp = new HashMap(); render(temp, obj); afterRender(temp, obj); result.add(temp); } } /** * ?? * @param map */ protected void afterRender(Map map, T obj) { } protected void retrieveAfterRender(Map map, T obj) { } protected void render(Map map, T obj) { //? List<Field> fields = ReflectionUtils.getDeclaredFields(model); for (Field field : fields) { if (field.isAnnotationPresent(RenderIgnore.class)) { continue; } addFieldValue(obj, field, map); } } /** * @param src * ? * @return src??srcnull */ public static String change(String src) { if (src != null) { StringBuilder sb = new StringBuilder(src); sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); return sb.toString(); } else { return null; } } protected String exportFileName() { return model.getMetaData() + ".xls"; } protected void renderForExport(List<List<String>> result) { List<String> data = new ArrayList<>(); //? List<Field> fields = ReflectionUtils.getDeclaredFields(model); for (Field field : fields) { if (field.isAnnotationPresent(ModelAttr.class)) { ModelAttr attr = field.getAnnotation(ModelAttr.class); String fieldAttr = attr.value(); data.add(fieldAttr); } } result.add(data); for (T obj : page.getModels()) { data = new ArrayList<>(); renderDataForExport(data, obj); result.add(data); } } private void renderDataForExport(List<String> data, T obj) { //? List<Field> fields = ReflectionUtils.getDeclaredFields(obj); for (Field field : fields) { if (field.isAnnotationPresent(ModelAttr.class)) { //??*_id Map<String, String> temp = new HashMap<>(); addFieldValue(obj, field, temp); //?? temp.remove(field.getName() + "_id"); data.addAll(temp.values()); } } } private void addFieldValue(T obj, Field field, List<String> data) { Map<String, String> temp = new HashMap<>(); addFieldValue(obj, field, temp); data.addAll(temp.values()); } private void addFieldValue(T obj, Field field, Map<String, String> data) { String fieldName = field.getName(); try { if (field.isAnnotationPresent(Lob.class)) { LOG.debug("[" + fieldName + "]?JSON"); return; } Object value = ReflectionUtils.getFieldValue(obj, field); if (value == null) { data.put(fieldName, ""); return; } //?? if (field.isAnnotationPresent(ModelCollRef.class)) { ModelCollRef ref = field.getAnnotation(ModelCollRef.class); String fieldRef = ref.value(); Collection col = (Collection) value; String colStr = ""; if (col != null) { LOG.debug("??," + field.getName() + ",?" + col.size()); if (col.size() > 0) { StringBuilder str = new StringBuilder(); for (Object m : col) { str.append(ReflectionUtils.getFieldValue(m, fieldRef).toString()).append(","); } str = str.deleteCharAt(str.length() - 1); colStr = str.toString(); } } else { LOG.debug("??" + value + " ???"); } data.put(fieldName, colStr); return; } //??? if (field.isAnnotationPresent(ModelAttrRef.class)) { LOG.debug("?," + field.getName()); ModelAttrRef ref = field.getAnnotation(ModelAttrRef.class); String fieldRef = ref.value(); //??ID Object id = ReflectionUtils.getFieldValue(value, "id"); data.put(fieldName + "_id", id.toString()); //?????? fieldName = fieldName + "_" + fieldRef; //?fieldRef value = ReflectionUtils.getFieldValue(value, fieldRef); } if (value.getClass() == null) { data.put(fieldName, ""); return; } String valueClass = value.getClass().getSimpleName(); if ("PersistentBag".equals(valueClass)) { value = ""; } if ("Timestamp".equals(valueClass) || "Date".equals(valueClass)) { if (field.isAnnotationPresent(RenderDate.class)) { value = DateTypeConverter.toDefaultDate((Date) value); } else if (field.isAnnotationPresent(RenderTime.class)) { value = DateTypeConverter.toDefaultDateTime((Date) value); } else { //?@Temporal? String temporal = "TIMESTAMP"; if (field.isAnnotationPresent(Temporal.class)) { temporal = field.getAnnotation(Temporal.class).value().name(); } switch (temporal) { case "TIMESTAMP": value = DateTypeConverter.toDefaultDateTime((Date) value); break; case "DATE": value = DateTypeConverter.toDefaultDate((Date) value); break; } } } //??? if ("DicItem".equals(valueClass)) { //?? data.put(fieldName + "Id", ReflectionUtils.getFieldValue(value, "id").toString()); value = ReflectionUtils.getFieldValue(value, "name"); } data.put(fieldName, value.toString()); } catch (Exception e) { LOG.error("?", e); } } public T getModel() { return this.model; } public void setModel(T model) { this.model = model; } public Page<T> getPage() { return page; } public void setPage(Page<T> page) { this.page = page; } public boolean isSearch() { return search; } public void setSearch(boolean search) { this.search = search; } protected void objectReference(T model) { Field[] fields = model.getClass().getDeclaredFields();//? for (Field field : fields) {// ?? if (field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToOne.class)) { LOG.debug(model.getMetaData() + " ManyToOne OneToOne" + field.getName()); Model value = (Model) ReflectionUtils.getFieldValue(model, field); if (value == null) { LOG.debug(model.getMetaData() + " " + field.getName() + "?"); continue; } int id = value.getId(); LOG.debug("id: " + id); value = getService().retrieve(value.getClass(), id); ReflectionUtils.setFieldValue(model, field, value); } } } }