帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
9.2 KiB

package com.fr.plugin.designer.toolbar;
import com.fr.base.extension.FileExtension;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.main.impl.WorkBook;
import com.fr.nx.compile.CompileStatus;
import com.fr.nx.compile.ReportCompiler;
import com.fr.nx.compile.adapter.LegacyWorkBookAdapter;
import com.fr.nx.compile.util.ReportCompileUtils;
import com.fr.nx.cptx.CptxIOManager;
import com.fr.nx.cptx.cache.CptxTemplatePool;
import com.fr.nx.cptx.entry.CptxTemplate;
import com.fr.nx.cptx.io.handle.CptxTemplateHandle;
import com.fr.plugin.designer.cptx.io.DesignReadWritableProvider;
import com.fr.nx.cptx.monitor.CompileMonitorHandler;
import com.fr.nx.cptx.utils.CptxFileUtils;
import com.fr.nx.data.layer.LayerItem;
import com.fr.nx.data.layer.LayerProps;
import com.fr.nx.template.compile.CompiledReport;
import com.fr.plugin.designer.monitor.DesignerMetricRecorder;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.io.OutputStream;
import static com.fr.base.extension.FileExtension.ALL;
import static com.fr.base.extension.FileExtension.CPT;
import static com.fr.base.extension.FileExtension.CPTX;
/**
* 模板转换器, 可以把cptx模板转为cpt, 或者cpt模板转为cptx.
* 以后可以扩展支持frm frmx互相转换
*/
public enum TemplateTransformer {
TO_CPTX(CPT) {
@Override
public TransformResult transform(JTemplate jtemplate, FILE file) {
WorkBook workbook = (WorkBook) jtemplate.getTarget();
TransformResultInfo resultInfo = compileCPTX(workbook, file);
if (needDoAfterTransformed(resultInfo.getResult())) {
doAfterTransformed(file, jtemplate);
}
return resultInfo.getResult();
}
},
TO_CPT(CPTX) {
@Override
public TransformResult transform(JTemplate jtemplate, FILE file) {
WorkBook workbook = (WorkBook) jtemplate.getTarget();
try {
workbook.export(file.asOutputStream());
doAfterTransformed(file, jtemplate);
return TransformResult.SUCCESS;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return TransformResult.FAILED;
}
}
},
OTHER(ALL);
private FileExtension extension;
TemplateTransformer(FileExtension extension) {
this.extension = extension;
}
public TransformResult transform(JTemplate jtemplate) {
return transform(jtemplate, jtemplate.getEditingFILE());
}
public TransformResult transform(JTemplate jtemplate, FILE newFile) {
return TransformResult.UNSUPPORT;
}
public static TemplateTransformer parse(String path) {
for (TemplateTransformer transformer : values()) {
if (transformer.extension.matchExtension(path)) {
return transformer;
}
}
return OTHER;
}
private static boolean needDoAfterTransformed(TransformResult result) {
return ComparatorUtils.equals(TransformResult.SUCCESS, result)
|| ComparatorUtils.equals(TransformResult.UNSUPPORT, result);
}
private static void doAfterTransformed(FILE file, JTemplate jtemplate) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (ComparatorUtils.equals(file.getPath(), jt.getPath())) {
HistoryTemplateListCache.getInstance().closeSelectedReport(jt);
DesignerContext.getDesignerFrame().openTemplate(file);
return;
}
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
DesignerContext.getDesignerFrame().openTemplate(file);
}
public static FILE createOutputFile(String oldPath, String oldSuffix, String newSuffix) {
String newPath = generateNewPath(oldPath, oldSuffix, newSuffix);
return new FileNodeFILE(new FileNode(newPath, false));
}
private static String generateNewPath(String oldPath, String oldSuffix, String newSuffix) {
if (StringUtils.isEmpty(oldPath) || StringUtils.isEmpty(oldSuffix) || StringUtils.isEmpty(newSuffix)) {
return oldPath;
}
if (oldPath.endsWith(oldSuffix)) {
return StringUtils.cutStringEndWith(oldPath, oldSuffix) + newSuffix;
}
return oldPath;
}
/**
* 编译和保存
*
* @param workbook work
* @param file file
* @return 编译保存结果
*/
@NotNull
public static TransformResultInfo compileCPTX(WorkBook workbook, FILE file) {
//对于非工作目录的cptx,修改无需执行编译
if(!(file instanceof FileNodeFILE)){
try {
OutputStream outputStream = file.asOutputStream();
workbook.export(outputStream);
return TransformResultInfo.generateResult(TransformResult.SUCCESS).saved(true);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return TransformResultInfo.generateResult(TransformResult.FAILED).saved(false);
}
}
boolean saved;
CompiledReport report = null;
CompileStatus compileStatus = CompileStatus.SUCCEED;
if (workbook == null || file == null) {
return TransformResultInfo
.generateResult(TransformResult.FAILED, "work and file must not be null")
.saved(false);
}
String failMessage = null;
// 编译
ReportCompiler compiler;
try {
compiler = new ReportCompiler(new LegacyWorkBookAdapter(workbook));
long startTime = System.currentTimeMillis();
compiler.compile();
report = compiler.getCompiledReport();
// 折叠树埋点
LayerProps props = ReportCompileUtils.getLayerProps(report);
LayerItem[] items;
if (props != null && (items = props.getLayerItems()) != null) {
CompileMonitorHandler.submitTreeCompileFocusPoint(
startTime, file.getPath(), items.length,
props.getExpandLayer(), true
);
}
compileStatus = compiler.getStatus();
failMessage = compiler.getFailMessage();
long endTime = System.currentTimeMillis();
CompileMonitorHandler.submitCompileMessage(startTime, endTime, file.getPath(), "");
if (compileStatus != CompileStatus.SUCCEED) {
DesignerMetricRecorder.submitUnSupportTransform(
TransformResult.UNSUPPORT,
workbook.getTemplateID(),
file.getName(),
compileStatus == CompileStatus.FAILED_UNSUPPORT ? failMessage : null
);
}
} catch (Exception exception) {
String templateID = workbook.getTemplateID();
String fileName = file.getName();
DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, templateID, fileName, exception);
FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
}
// 构建编译结果,当前的 cptx template 是未经反序列化钩子处理过的 cptx 模版对象,不能直接用于模版预览
CptxTemplate template = CptxIOManager.createCptxTemplate(workbook, report, compileStatus, failMessage);
// 保存
DesignReadWritableProvider cptx = new DesignReadWritableProvider(file);
CptxTemplateHandle handle = CptxIOManager.create(template, cptx);
try {
saved = handle.save();
} catch (Exception exception) {
// 存储cptx格式报错或者失败
FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, workbook.getTemplateID(), file.getName(), exception);
return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(false);
}
// 读取可 web 预览模版并缓存
try {
// todo 是否考虑异步
String timestampedPath = CptxFileUtils.getTimestampedPath(file.getPath());
CptxTemplate previewCptxTemplate = CptxIOManager.open(cptx).getTemplate();
CptxTemplatePool.getInstance().addCptxTemplate(timestampedPath, previewCptxTemplate);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (report == null) {
// 编译报错或者失败
return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(saved);
}
return TransformResultInfo.generateResult(TransformResult.parse(compileStatus), failMessage).saved(saved);
}
}