//$Id:ModelDrivenAction.java 2009-1-20 下午06:43:56 chaostone Exp $
/*
* Copyright c 2005-2009.
*
* Licensed under the GPL License, Version 2.0 (the "License")
* http://www.gnu.org/licenses/gpl-2.0.html
*
*/
package org.beanfuse.struts2.action;
import static org.beanfuse.utils.web.RequestUtils.encodeAttachName;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Serializable;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.beanfuse.collection.Order;
import org.beanfuse.entity.Model;
import org.beanfuse.entity.types.EntityType;
import org.beanfuse.lang.SeqStringUtil;
import org.beanfuse.model.Entity;
import org.beanfuse.model.EntityUtils;
import org.beanfuse.model.LongIdTimeEntity;
import org.beanfuse.query.EntityQuery;
import org.beanfuse.transfer.Transfer;
import org.beanfuse.transfer.TransferListener;
import org.beanfuse.transfer.TransferResult;
import org.beanfuse.transfer.exporter.Context;
import org.beanfuse.transfer.exporter.DefaultEntityExporter;
import org.beanfuse.transfer.exporter.DefaultPropertyExtractor;
import org.beanfuse.transfer.exporter.Exporter;
import org.beanfuse.transfer.exporter.ItemExporter;
import org.beanfuse.transfer.exporter.PropertyExtractor;
import org.beanfuse.transfer.exporter.TemplateExporter;
import org.beanfuse.transfer.exporter.writer.ExcelItemWriter;
import org.beanfuse.transfer.exporter.writer.ExcelTemplateWriter;
import org.beanfuse.transfer.exporter.writer.TemplateWriter;
import org.beanfuse.transfer.importer.DefaultEntityImporter;
import org.beanfuse.transfer.importer.EntityImporter;
import org.beanfuse.transfer.importer.listener.ImporterForeignerListener;
import org.beanfuse.transfer.importer.reader.CSVReader;
import org.beanfuse.transfer.importer.reader.ExcelItemReader;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ClassLoaderUtil;
public class EntityDrivenAction extends BaseAction {
protected String entityName;
/**
* 主页面
*
* @return
* @throws Exception
*/
public String index() throws Exception {
indexSetting();
return forward();
}
/**
* 查找标准
*
* @return
* @throws Exception
*/
public String search() throws Exception {
put(getShortName() + "s", search(buildQuery()));
return forward();
}
protected Collection getExportDatas() {
EntityQuery query = buildQuery();
query.setLimit(null);
return search(query);
}
/**
* 修改标准
*
* @return
* @throws Exception
*/
public String edit() throws Exception {
Long entityId = getEntityId(getShortName());
Entity entity = null;
if (null == entityId) {
entity = populateEntity();
} else {
entity = getModel(getEntityName(), entityId);
}
put(getShortName(), entity);
editSetting(entity);
return forward();
}
/**
* 删除
*
* @return
* @throws Exception
*/
public String remove() throws Exception {
Long entityId = getLong(getShortName() + "Id");
Collection entities = null;
if (null == entityId) {
String entityIdSeq = get(getShortName() + "Ids");
entities = getModels(getEntityName(), SeqStringUtil.transformToLong(entityIdSeq));
} else {
Entity entity = getModel(getEntityName(), entityId);
entities = Collections.singletonList(entity);
}
return removeAndForward(entities);
}
/**
* 保存修改后的标准
*
* @return
* @throws Exception
*/
public String save() throws Exception {
return saveAndForward(populateEntity());
}
protected Entity populateEntity() {
return populateEntity(getEntityName(), getShortName());
}
protected Long getEntityId(String shortName) {
Long entityId = getLong("id");
if (null == entityId) {
entityId = getLong(shortName + ".id");
}
if (null == entityId) {
entityId = getLong(shortName + "Id");
}
return entityId;
}
protected Entity populateEntity(String entityName, String shortName) {
Long entityId = getEntityId(shortName);
Entity entity = null;
if (null == entityId) {
entity = (Entity) populate(entityName, shortName);
} else {
Map params = getParams(shortName);
entity = getModel(entityName, entityId);
populate(params, entity, entityName);
}
return entity;
}
protected Entity populateEntity(Class entityClass, String shortName) {
EntityType type = null;
if (entityClass.isInterface()) {
type = Model.getEntityType(entityClass.getName());
} else {
type = Model.getEntityType(entityClass);
}
return populateEntity(type.getEntityName(), shortName);
}
protected Entity getEntity() {
return getEntity(getEntityName(), getShortName());
}
protected Entity getEntity(String entityName, String name) {
Long entityId = getEntityId(name);
Entity entity = null;
try {
EntityType type = Model.getEntityType(entityName);
if (null == entityId) {
entity = (Entity) populate(type.newInstance(), type.getEntityName(), name);
} else {
entity = getModel(entityName, entityId);
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return entity;
}
protected Entity getEntity(Class entityClass, String shortName) {
EntityType type = null;
if (entityClass.isInterface()) {
type = Model.getEntityType(entityClass.getName());
} else {
type = Model.getEntityType(entityClass);
}
return getEntity(type.getEntityName(), shortName);
}
/**
* 查看信息
*
* @return
* @throws Exception
*/
public String info() throws Exception {
Long entityId = getEntityId(getShortName());
if (null == entityId) {
logger.warn("cannot get paremeter {}Id or {}.id", getShortName(), getShortName());
}
Entity entity = getModel(getEntityName(), entityId);
put(getShortName(), entity);
return forward();
}
protected void indexSetting() {
}
protected void editSetting(Entity entity) {
}
/**
* 保存对象
*
* @param entity
* @return
*/
protected String saveAndForward(Entity entity) {
try {
if (entity instanceof LongIdTimeEntity) {
LongIdTimeEntity timeEntity = (LongIdTimeEntity) entity;
if (timeEntity.isVO()) {
timeEntity.setCreatedAt(new Date());
}
timeEntity.setUpdatedAt(new Date());
}
saveOrUpdate(Collections.singletonList(entity));
return redirect("search", "info.save.success");
} catch (Exception e) {
logger.info("saveAndForwad failure", e);
return redirect("search", "info.save.failure");
}
}
protected String removeAndForward(Collection entities) {
try {
remove(entities);
} catch (Exception e) {
logger.info("removeAndForwad failure", e);
return redirect("search", "info.delete.failure");
}
return redirect("search", "info.delete.success");
}
protected EntityQuery buildQuery() {
EntityQuery query = new EntityQuery(getEntityName(), getShortName());
populateConditions(query);
query.addOrder(Order.parse(get("orderBy")));
query.setLimit(getPageLimit());
return query;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
protected String getEntityName() {
if (null == entityName) {
logger.error("entity name not setted for {}", getClass().getName());
}
return entityName;
}
protected String getShortName() {
if (StringUtils.isNotEmpty(getEntityName())) {
return EntityUtils.getCommandName(getEntityName());
}
return null;
}
protected Entity getModel(String entityName, Serializable id) {
return entityService.get(entityName, id);
}
protected List getModels(String entityName, Long[] ids) {
return entityService.load(entityName, "id", ids);
}
protected List getModels(Class modelClass, Long[] ids) {
return entityService.load(modelClass, "id", ids);
}
/**
* 数据输出
*
* @param mapping
* @param request
* @param forwardTag
* @param detailObject
* @return
*/
public String export() throws Exception {
// 查找导出参数
String format = get("format");
String fileName = get("fileName");
String template = get("template");
if (StringUtils.isBlank(format)) {
format = Transfer.EXCEL;
}
if (StringUtils.isEmpty(fileName)) {
fileName = "exportResult";
}
// 配置导出上下文
Context context = new Context();
context.put("format", format);
context.put("exportFile", fileName);
if (StringUtils.isNotBlank(template)) {
URL templateURL = loadTemplate(template);
if (null != templateURL) {
context.getDatas().put(TemplateWriter.TEMPLATE_PATH, templateURL);
}
}
configExportContext(context);
// 构造合适的输出器
Collection datas = (Collection) context.get("items");
boolean isArray = false;
if (!CollectionUtils.isEmpty(datas)) {
Object first = datas.iterator().next();
if (first.getClass().isArray()) {
isArray = true;
}
}
Exporter exporter;
if (isArray) {
exporter = new ItemExporter();
} else {
if (StringUtils.isNotBlank(template)) {
exporter = new TemplateExporter();
} else {
exporter = new DefaultEntityExporter();
((DefaultEntityExporter) exporter)
.setAttrs(StringUtils.split(getExportKeys(), ","));
((DefaultEntityExporter) exporter).setPropertyExtractor(getPropertyExtractor());
}
}
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
// 设置下载项信息
if (exporter instanceof ItemExporter) {
((ItemExporter) exporter).setTitles(StringUtils.split(getExportTitles(), ","));
exporter.setWriter(new ExcelItemWriter(response.getOutputStream()));
} else {
exporter.setWriter(new ExcelTemplateWriter(response.getOutputStream()));
}
if (format.equals(Transfer.EXCEL)) {
response.setContentType("application/vnd.ms-excel;charset=GBK");
response.setHeader("Content-Disposition", "attachment;filename="
+ encodeAttachName(request, context.getDatas().get("exportFile").toString()
+ ".xls"));
} else {
throw new RuntimeException("Exporter is not supported for other format:"
+ exporter.getFormat());
}
// 进行输出
exporter.setContext(context);
exporter.transfer(new TransferResult());
return null;
}
protected URL loadTemplate(String template) {
URL url = ClassLoaderUtil.getResource(template, getClass());
if (url == null) {
logger.error("Cannot load template {}", template);
}
return url;
}
protected void configExportContext(Context context) {
Collection datas = getExportDatas();
context.getDatas().put("items", datas);
}
protected PropertyExtractor getPropertyExtractor() {
return new DefaultPropertyExtractor(new ActionTextResource(this));
}
protected String getExportKeys() {
return get("keys");
}
protected String getExportTitles() {
return get("titles");
}
public String importForm() {
return forward("/components/importData/form");
}
/**
* 构建实体导入者
*
* @return
*/
protected EntityImporter buildEntityImporter() {
if (null == getEntityName()) {
return buildEntityImporter("importFile", null);
} else {
return buildEntityImporter("importFile", Model.getEntityType(getEntityName())
.getEntityClass());
}
}
protected EntityImporter buildEntityImporter(Class clazz) {
return buildEntityImporter("importFile", clazz);
}
/**
* 构建实体导入者
*
* @param upload
* @param clazz
* @return
*/
protected EntityImporter buildEntityImporter(String upload, Class clazz) {
try {
File[] files = (File[]) ActionContext.getContext().getParameters().get(upload);
if (files == null || files.length < 1) {
logger.error("cannot get {} file.", upload);
}
String fileName = get(upload + "FileName");
InputStream is = new FileInputStream(files[0]);
if (fileName.endsWith(".xls")) {
HSSFWorkbook wb = new HSSFWorkbook(is);
if (wb.getNumberOfSheets() < 1 || wb.getSheetAt(0).getLastRowNum() == 0) {
return null;
}
EntityImporter importer = (clazz == null) ? new DefaultEntityImporter()
: new DefaultEntityImporter(clazz);
importer.setReader(new ExcelItemReader(wb, 1));
put("importer", importer);
return importer;
} else {
LineNumberReader reader = new LineNumberReader(new InputStreamReader(is));
if (null == reader.readLine())
return null;
reader.reset();
EntityImporter importer = (clazz == null) ? new DefaultEntityImporter()
: new DefaultEntityImporter(clazz);
importer.setReader(new CSVReader(reader));
return importer;
}
} catch (Exception e) {
logger.error("error", e);
return null;
}
}
/**
* 导入班级信息
*
* @param mapping
* @param form
* @param request
* @param response
* @return @
*/
public String importData() {
TransferResult tr = new TransferResult();
EntityImporter importer = buildEntityImporter();
if (null == importer) {
return forward("/components/importData/error");
}
configImporter(importer);
importer.transfer(tr);
put("importResult", tr);
if (tr.hasErrors()) {
return forward("/components/importData/error");
} else {
return forward("/components/importData/result");
}
}
protected void configImporter(EntityImporter importer) {
for (Iterator iter = getImporterListeners().iterator(); iter.hasNext();) {
TransferListener il = (TransferListener) iter.next();
importer.addListener(il);
}
}
protected List getImporterListeners() {
return Collections.singletonList(new ImporterForeignerListener(entityService));
}
}