LAPTOP-SB56SG4Q\86185
3 years ago
16 changed files with 752 additions and 1 deletions
@ -1,3 +1,6 @@
|
||||
# demo-template-encrypt |
||||
|
||||
模板综合加解密专题示例 |
||||
模板综合加解密专题示例\ |
||||
demo生效后,可以在设计器的 模板 工具栏中 增加一个模板密钥的菜单项\ |
||||
选择后,可以为当前正在编辑的模板设置一个加密密钥。\ |
||||
设置密钥的模板会被密钥加密,以后编辑时都需要先输入并验证密钥的正确后才能正常编辑 |
@ -0,0 +1,125 @@
|
||||
|
||||
apply plugin: 'java' |
||||
|
||||
[compileJava,compileTestJava]*.options*.encoding = 'UTF-8' |
||||
|
||||
ext { |
||||
/** |
||||
* 项目中依赖的jar的路径 |
||||
* 1.如果依赖的jar需要打包到zip中,放置在lib根目录下 |
||||
* 2.如果依赖的jar仅仅是编译时需要,防止在lib下子目录下即可 |
||||
*/ |
||||
libPath = "$projectDir/../../webroot/WEB-INF/lib" |
||||
|
||||
/** |
||||
* 是否对插件的class进行加密保护,防止反编译 |
||||
*/ |
||||
guard = true |
||||
|
||||
def pluginInfo = getPluginInfo() |
||||
pluginPre = "fine-plugin" |
||||
pluginName = pluginInfo.id |
||||
pluginVersion = pluginInfo.version |
||||
|
||||
outputPath = "$projectDir/../../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes" |
||||
} |
||||
|
||||
group = 'com.fr.plugin' |
||||
version = '10.0' |
||||
sourceCompatibility = '8' |
||||
|
||||
sourceSets { |
||||
main { |
||||
java.outputDir = file(outputPath) |
||||
output.resourcesDir = file(outputPath) |
||||
} |
||||
} |
||||
|
||||
ant.importBuild("encrypt.xml") |
||||
//定义ant变量 |
||||
ant.projectDir = projectDir |
||||
ant.references["compile.classpath"] = ant.path { |
||||
fileset(dir: libPath, includes: '**/*.jar') |
||||
fileset(dir: ".",includes:"**/*.jar" ) |
||||
} |
||||
|
||||
classes.dependsOn('clean') |
||||
|
||||
task copyFiles(type: Copy,dependsOn: 'classes'){ |
||||
from outputPath |
||||
into "$projectDir/classes" |
||||
} |
||||
|
||||
task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){ |
||||
from "$projectDir/classes" |
||||
into "$projectDir/transform-classes" |
||||
include "**/*.*" |
||||
} |
||||
jar.dependsOn("preJar") |
||||
|
||||
task makeJar(type: Jar,dependsOn: preJar){ |
||||
from fileTree(dir: "$projectDir/transform-classes") |
||||
baseName pluginPre |
||||
appendix pluginName |
||||
version pluginVersion |
||||
destinationDir = file("$buildDir/libs") |
||||
|
||||
doLast(){ |
||||
delete file("$projectDir/classes") |
||||
delete file("$projectDir/transform-classes") |
||||
} |
||||
} |
||||
|
||||
task copyFile(type: Copy,dependsOn: ["makeJar"]){ |
||||
from "$buildDir/libs" |
||||
from("$projectDir/lib") { |
||||
include "*.jar" |
||||
} |
||||
from "$projectDir/plugin.xml" |
||||
into file("$buildDir/temp/plugin") |
||||
} |
||||
|
||||
task zip(type:Zip,dependsOn:["copyFile"]){ |
||||
from "$buildDir/temp/plugin" |
||||
destinationDir file("$buildDir/install") |
||||
baseName pluginPre |
||||
appendix pluginName |
||||
version pluginVersion |
||||
} |
||||
|
||||
//控制build时包含哪些文件,排除哪些文件 |
||||
processResources { |
||||
// exclude everything |
||||
// 用*.css没效果 |
||||
// exclude '**/*.css' |
||||
// except this file |
||||
// include 'xx.xml' |
||||
} |
||||
|
||||
/*读取plugin.xml中的version*/ |
||||
def getPluginInfo(){ |
||||
def xmlFile = file("plugin.xml") |
||||
if (!xmlFile.exists()) { |
||||
return ["id":"none", "version":"1.0.0"] |
||||
} |
||||
def plugin = new XmlParser().parse(xmlFile) |
||||
def version = plugin.version[0].text() |
||||
def id = plugin.id[0].text() |
||||
return ["id":id,"version":version] |
||||
} |
||||
|
||||
repositories { |
||||
mavenLocal() |
||||
maven { |
||||
url = uri('http://mvn.finedevelop.com/repository/maven-public/') |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
//implementation project(":tools:tool-dynamic-agent") |
||||
//使用本地jar |
||||
implementation fileTree(dir: 'lib', include: ['**/*.jar']) |
||||
implementation fileTree(dir: libPath, include: ['**/*.jar']) |
||||
} |
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<project> |
||||
<target name="compile_encrypt_javas" depends="copyFiles"> |
||||
<echo message="加密文件"/> |
||||
<echo message="${projectDir}"/> |
||||
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask"> |
||||
<classpath refid="compile.classpath"/> |
||||
</taskdef> |
||||
<pretreatment baseDir="${projectDir}"/> |
||||
</target> |
||||
<target name="compile_plain_javas" depends="copyFiles"> |
||||
</target> |
||||
</project> |
Binary file not shown.
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||
<id>com.tptj.demo.hg.template.encrypt.v10</id> |
||||
<name><![CDATA[ template encrypt ]]></name> |
||||
<active>yes</active> |
||||
<version>1.0</version> |
||||
<env-version>10.0</env-version> |
||||
<vendor>tptj</vendor> |
||||
<jartime>2019-07-18</jartime> |
||||
<description><![CDATA[ ]]></description> |
||||
<change-notes><![CDATA[]]></change-notes> |
||||
<main-package>com.tptj.demo.hg.template.encrypt</main-package> |
||||
<function-recorder class="com.tptj.demo.hg.template.encrypt.LifeCycle"/> |
||||
<lifecycle-monitor class="com.tptj.demo.hg.template.encrypt.LifeCycle"/> |
||||
<extra-core> |
||||
<IOFileAttrMark class="com.tptj.demo.hg.template.encrypt.ui.SpEncryptAttrMark"/> |
||||
</extra-core> |
||||
<extra-designer> |
||||
<MenuHandler class="com.tptj.demo.hg.template.encrypt.ui.MenuEncryptor"/> |
||||
</extra-designer> |
||||
<extra-report> |
||||
<TemplateEncryptProvider class="com.tptj.demo.hg.template.encrypt.DemoEncryptor"/> |
||||
</extra-report> |
||||
</plugin> |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.mainframe.app; |
||||
|
||||
import com.fr.file.FILE; |
||||
import com.fr.main.impl.WorkBook; |
||||
import com.tptj.demo.hg.template.encrypt.BaseInterceptor; |
||||
import com.tptj.tool.hg.dynamic.agent.source.AccessPoint; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Context; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Source; |
||||
import com.tptj.tool.hg.dynamic.agent.version.ModuleReport; |
||||
import com.tptj.tool.hg.dynamic.agent.version.VersionChecker; |
||||
|
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/11 |
||||
**/ |
||||
@VersionChecker(value = 10020210101l, loader = ModuleReport.class) |
||||
@Source(CptApp.class) |
||||
public class SpCptApp extends Context { |
||||
|
||||
@AccessPoint |
||||
public WorkBook asIOFile(FILE file, boolean needCheck) { |
||||
BaseInterceptor.intercept4Edit(file); |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,29 @@
|
||||
package com.fr.design.mainframe.app; |
||||
|
||||
import com.fr.base.io.EncryptIOFileProxy; |
||||
import com.tptj.demo.hg.template.encrypt.BaseInterceptor; |
||||
import com.tptj.tool.hg.dynamic.agent.source.AccessPoint; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Context; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Source; |
||||
import com.tptj.tool.hg.dynamic.agent.version.ModuleReport; |
||||
import com.tptj.tool.hg.dynamic.agent.version.VersionChecker; |
||||
|
||||
import java.io.OutputStream; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/11 |
||||
* 注入EncryptIOFileProxy#export的切面,在保存模板时,传递密钥信息,以便加密 |
||||
**/ |
||||
@VersionChecker(value = 10020210101l, loader = ModuleReport.class) |
||||
@Source(EncryptIOFileProxy.class) |
||||
public class SpEncryptIOFileProxy extends Context { |
||||
|
||||
@AccessPoint |
||||
public boolean export(OutputStream out) throws Exception { |
||||
BaseInterceptor.intercept4Save(getOrigin()); |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.mainframe.app; |
||||
|
||||
import com.fr.file.FILE; |
||||
import com.fr.form.main.Form; |
||||
import com.tptj.demo.hg.template.encrypt.BaseInterceptor; |
||||
import com.tptj.tool.hg.dynamic.agent.source.AccessPoint; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Context; |
||||
import com.tptj.tool.hg.dynamic.agent.source.Source; |
||||
import com.tptj.tool.hg.dynamic.agent.version.ModuleReport; |
||||
import com.tptj.tool.hg.dynamic.agent.version.VersionChecker; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
* 注入FormApp#asIOFile 的切面,在打开加密form时,注入密码输入UI交互 |
||||
**/ |
||||
@VersionChecker(value = 10020210101l, loader = ModuleReport.class) |
||||
@Source(FormApp.class) |
||||
public class SpFormApp extends Context { |
||||
|
||||
@AccessPoint |
||||
public Form asIOFile(FILE file) { |
||||
BaseInterceptor.intercept4Edit(file); |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,46 @@
|
||||
package com.tptj.demo.hg.template.encrypt; |
||||
|
||||
import com.fr.base.io.EncryptIOFileProxy; |
||||
import com.fr.base.io.IOFile; |
||||
import com.fr.file.FILE; |
||||
import com.fr.invoke.Reflect; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.tptj.demo.hg.template.encrypt.ui.DecodeDialog; |
||||
import com.tptj.demo.hg.template.encrypt.ui.SpEncryptAttrMark; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class BaseInterceptor { |
||||
/** |
||||
* 在打开模板前对加密的模板插入输入密码的弹窗 |
||||
* @param file |
||||
*/ |
||||
public static void intercept4Edit(FILE file){ |
||||
try { |
||||
file.asInputStream(); |
||||
if( !DemoEncryptor.hasSecret() ){ |
||||
return; |
||||
} |
||||
String secret = DemoEncryptor.getSecret(); |
||||
secret = new DecodeDialog(file,secret).getSecret(); |
||||
DemoEncryptor.setSecret(secret); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e,e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 在保存模板前获取配置的模板密钥,以便加密接口进行加密 |
||||
* @param origin |
||||
*/ |
||||
public static void intercept4Save( EncryptIOFileProxy origin ){ |
||||
IOFile report = Reflect.on(origin).get("file"); |
||||
SpEncryptAttrMark mark = report.getAttrMark(SpEncryptAttrMark.XML_TAG); |
||||
if( null != mark ){ |
||||
DemoEncryptor.setSecret(mark.getSecret()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,117 @@
|
||||
package com.tptj.demo.hg.template.encrypt; |
||||
|
||||
import com.fr.general.CommonIOUtils; |
||||
import com.fr.report.fun.impl.AbstractTemplateEncryptProvider; |
||||
import com.fr.security.SecurityToolbox; |
||||
import com.fr.stable.CodeUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.InputStream; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class DemoEncryptor extends AbstractTemplateEncryptProvider { |
||||
|
||||
public static final String TAG_START = "-----Encrypt Start-----"; |
||||
public static final String TAG_END = "-----Encrypt End-----"; |
||||
|
||||
public static ThreadLocal<String> holder = new ThreadLocal<String>(); |
||||
public static ThreadLocal<Integer> pos = new ThreadLocal<Integer>(); |
||||
public static ThreadLocal<Boolean> init = new ThreadLocal<Boolean>(); |
||||
|
||||
public static void setSecret(String secret) { |
||||
holder.set(secret); |
||||
} |
||||
|
||||
public static String getSecret() { |
||||
return holder.get(); |
||||
} |
||||
|
||||
public static boolean hasSecret() { |
||||
return StringUtils.isNotEmpty(getSecret()); |
||||
} |
||||
|
||||
public static int getPos(){ |
||||
return pos.get(); |
||||
} |
||||
|
||||
public static void setPos(int idx){ |
||||
pos.set(idx); |
||||
} |
||||
|
||||
public static void initData(InputStream in){ |
||||
init.set(true); |
||||
String data = StringUtils.EMPTY; |
||||
try{ |
||||
data = CommonIOUtils.inputStream2String(in); |
||||
if(!data.startsWith(TAG_START)){ |
||||
setSecret(StringUtils.EMPTY); |
||||
setPos(-1); |
||||
return; |
||||
} |
||||
int end = data.indexOf(TAG_END); |
||||
String part = data.substring(TAG_START.length(),end); |
||||
String sha = part.substring(0,64); |
||||
String code = part.substring(64); |
||||
String secret = CodeUtils.passwordDecode("___"+code); |
||||
if( !CodeUtils.md5Encode(secret, StringUtils.EMPTY,"SHA-256").equals(sha) ){ |
||||
setSecret(StringUtils.EMPTY); |
||||
setPos(-1); |
||||
return; |
||||
} |
||||
setSecret(secret); |
||||
setPos(end+TAG_END.length()); |
||||
}catch(Exception e){ |
||||
setSecret(StringUtils.EMPTY); |
||||
setPos(-1); |
||||
} |
||||
} |
||||
|
||||
private String codePassword(){ |
||||
String secret = getSecret(); |
||||
String code = CodeUtils.passwordEncode(secret).substring(3); |
||||
String sha = CodeUtils.md5Encode(secret, StringUtils.EMPTY,"SHA-256"); |
||||
return sha+code; |
||||
} |
||||
|
||||
@Override |
||||
public InputStream encode(InputStream in) { |
||||
if( !hasSecret() ){ |
||||
return in; |
||||
} |
||||
byte[] bytes = CommonIOUtils.inputStream2Bytes(in); |
||||
try{ |
||||
String secret = getSecret(); |
||||
String data = new String(bytes,"UTF-8"); |
||||
data = TAG_START +codePassword()+TAG_END+ |
||||
SecurityToolbox.aesEncrypt( data, secret); |
||||
return new ByteArrayInputStream(data.getBytes("UTF-8")); |
||||
}catch (Exception e){ |
||||
return new ByteArrayInputStream(bytes); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public InputStream decode(InputStream in) { |
||||
byte[] bytes = CommonIOUtils.inputStream2Bytes(in); |
||||
try{ |
||||
if( !Boolean.TRUE.equals(init.get()) ){ |
||||
initData(new ByteArrayInputStream(bytes)); |
||||
} |
||||
if( !hasSecret() ){ |
||||
return new ByteArrayInputStream(bytes); |
||||
} |
||||
String data = new String(bytes,"UTF-8"); |
||||
data = data.substring( getPos() ); |
||||
data = SecurityToolbox.aesDecrypt( data, getSecret() ); |
||||
return new ByteArrayInputStream(data.getBytes("UTF-8")); |
||||
}catch (Exception e){ |
||||
return new ByteArrayInputStream(bytes); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,35 @@
|
||||
package com.tptj.demo.hg.template.encrypt; |
||||
|
||||
import com.fr.design.mainframe.app.SpCptApp; |
||||
import com.fr.design.mainframe.app.SpEncryptIOFileProxy; |
||||
import com.fr.design.mainframe.app.SpFormApp; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.tptj.tool.hg.dynamic.agent.base.DynamicAgent; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/11 |
||||
**/ |
||||
@EnableMetrics |
||||
public class LifeCycle extends AbstractPluginLifecycleMonitor { |
||||
public static final String PLUGIN_ID = "com.tptj.demo.hg.template.encrypt.v10"; |
||||
public static final String PLUGIN_NAME = "template encrypt"; |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = PLUGIN_NAME) |
||||
public void afterRun(PluginContext context) { |
||||
DynamicAgent.getInstance().register( |
||||
new SpEncryptIOFileProxy(), |
||||
new SpCptApp(), |
||||
new SpFormApp()); |
||||
} |
||||
|
||||
@Override |
||||
public void beforeStop(PluginContext context) { |
||||
DynamicAgent.getInstance().reset(); |
||||
} |
||||
} |
@ -0,0 +1,88 @@
|
||||
package com.tptj.demo.hg.template.encrypt.ui; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.file.FILE; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class DecodeDialog { |
||||
private UITextField jt; |
||||
private UIButton confirmButton; |
||||
private UILabel hintsLabel; |
||||
private JDialog jd; |
||||
private FILE file; |
||||
private String secret = StringUtils.EMPTY; |
||||
|
||||
public DecodeDialog(final FILE file, final String key) { |
||||
this.file = file; |
||||
|
||||
jd = new JDialog(); |
||||
jd.setLayout(null); |
||||
UILabel newNameLable = new UILabel(Toolkit.i18nText("Fine-Design_Basic_ECP_Input_Pwd")); |
||||
newNameLable.setBounds(20, 10, 130, 30); |
||||
jt = new UITextField(StringUtils.EMPTY); |
||||
jt.selectAll(); |
||||
jt.setBounds(130, 15, 150, 20); |
||||
jd.add(newNameLable); |
||||
jd.add(jt); |
||||
|
||||
hintsLabel = new UILabel(); |
||||
hintsLabel.setBounds(20, 50, 250, 30); |
||||
hintsLabel.setForeground(Color.RED); |
||||
hintsLabel.setVisible(false); |
||||
|
||||
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm")); |
||||
confirmButton.setBounds(180, 90, 60, 25); |
||||
confirmButton.addActionListener(new ActionListener() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
secret = jt.getText(); |
||||
if(ComparatorUtils.equals(secret, key)){ |
||||
jd.dispose(); |
||||
}else{ |
||||
hintsLabel.setText(Toolkit.i18nText("Fine-Design_Basic_ECP_Re_Input")); |
||||
hintsLabel.setVisible(true); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); |
||||
cancelButton.setBounds(250, 90, 60, 25); |
||||
cancelButton.addActionListener(new ActionListener() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
jd.dispose(); |
||||
} |
||||
}); |
||||
|
||||
jd.add(cancelButton); |
||||
jd.add(confirmButton); |
||||
jd.add(hintsLabel); |
||||
jd.setSize(340, 180); |
||||
jd.setModal(true); |
||||
jd.setTitle(Toolkit.i18nText("Fine-Design_Basic_ECP_Decode")); |
||||
jd.setResizable(false); |
||||
jd.setAlwaysOnTop(true); |
||||
jd.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); |
||||
jd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); |
||||
GUICoreUtils.centerWindow(jd); |
||||
jd.setVisible(true); |
||||
} |
||||
|
||||
public String getSecret() { |
||||
return secret; |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.tptj.demo.hg.template.encrypt.ui; |
||||
|
||||
import com.fr.base.io.AttrMark; |
||||
import com.fr.base.svg.IconUtils; |
||||
import com.fr.design.actions.JTemplateAction; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.dialog.UIDialog; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.report.fit.FitProvider; |
||||
|
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class MenuEncryptAction extends JTemplateAction { |
||||
private static final Dimension MEDIUM = new Dimension(300, 120); |
||||
public MenuEncryptAction(JTemplate template) { |
||||
super(template); |
||||
setName("模板加密"); |
||||
setSmallIcon(IconUtils.readIcon("com/fr/design/images/buttonicon/icon_lock_enabled.png")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
JTemplate jwb = getEditingComponent(); |
||||
if ( null == jwb ) { |
||||
return; |
||||
} |
||||
//当前的模板
|
||||
FitProvider wbTpl = (FitProvider) jwb.getTarget(); |
||||
if( jwb.isJWorkBook() ){ |
||||
//如果是cpt
|
||||
}else{ |
||||
//不是cpt
|
||||
} |
||||
SecretPane pane = new SecretPane( (AttrMark) wbTpl ); |
||||
UIDialog dialog = pane.showUnsizedWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
//做某些操作 从 pane中读取相关的交互结果设置到当前的模板中一般是这样
|
||||
pane.update(); |
||||
jwb.fireTargetModified(); |
||||
} |
||||
}); |
||||
pane.populate(); |
||||
dialog.setSize(MEDIUM); |
||||
dialog.setVisible(true); |
||||
} |
||||
} |
@ -0,0 +1,49 @@
|
||||
package com.tptj.demo.hg.template.encrypt.ui; |
||||
|
||||
import com.fr.design.fun.impl.AbstractMenuHandler; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; |
||||
import com.fr.design.menu.ShortCut; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class MenuEncryptor extends AbstractMenuHandler { |
||||
private static final int INSERT_POSITION = 2; |
||||
@Override |
||||
public int insertPosition(int i) { |
||||
return INSERT_POSITION; |
||||
} |
||||
|
||||
@Override |
||||
public boolean insertSeparatorBefore() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean insertSeparatorAfter() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public String category() { |
||||
return TEMPLATE; |
||||
} |
||||
|
||||
@Override |
||||
public ShortCut shortcut(){ |
||||
JTemplate template = DesignerContext.getDesignerFrame().getSelectedJTemplate(); |
||||
return shortcut(template); |
||||
} |
||||
@Override |
||||
public ShortCut shortcut(ToolBarMenuDockPlus plus) { |
||||
//往ToolBarMenuDockPlus里塞感觉也很糟.
|
||||
if (!(plus instanceof JTemplate)){ |
||||
return null; |
||||
} |
||||
return new MenuEncryptAction( (JTemplate)plus ); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.tptj.demo.hg.template.encrypt.ui; |
||||
|
||||
import com.fr.base.io.AttrMark; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class SecretPane extends BasicPane { |
||||
|
||||
private UITextField w_secret; |
||||
private AttrMark container; |
||||
public SecretPane( AttrMark container ){ |
||||
this.container = container; |
||||
w_secret = new UITextField(); |
||||
setLayout(FRGUIPaneFactory.createM_BorderLayout()); |
||||
JPanel pane = TableLayoutHelper.createTableLayoutPane( |
||||
new Component[][]{ |
||||
{new UILabel("加密密钥:"), w_secret} |
||||
}, |
||||
new double[]{TableLayout.PREFERRED}, |
||||
new double[]{ TableLayout.PREFERRED,TableLayout.FILL} |
||||
); |
||||
add( pane, BorderLayout.NORTH ); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return "设置模板密钥"; |
||||
} |
||||
|
||||
public void populate(){ |
||||
SpEncryptAttrMark attr = container.getAttrMark(SpEncryptAttrMark.XML_TAG); |
||||
if( null != attr ){ |
||||
w_secret.setText( attr.getSecret() ); |
||||
} |
||||
} |
||||
|
||||
public void update(){ |
||||
SpEncryptAttrMark attr = new SpEncryptAttrMark(); |
||||
attr.setSecret( w_secret.getText() ); |
||||
container.addAttrMark( attr ); |
||||
} |
||||
} |
@ -0,0 +1,59 @@
|
||||
package com.tptj.demo.hg.template.encrypt.ui; |
||||
|
||||
import com.fr.json.JSONException; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.fun.impl.AbstractIOFileAttrMark; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
|
||||
/** |
||||
* @author 秃破天际 |
||||
* @version 10.0 |
||||
* Created by 秃破天际 on 2021/9/12 |
||||
**/ |
||||
public class SpEncryptAttrMark extends AbstractIOFileAttrMark { |
||||
public final static String XML_TAG = "SpEncryptAttrMark"; |
||||
|
||||
private String secret; |
||||
|
||||
public String getSecret() { |
||||
return secret; |
||||
} |
||||
|
||||
public void setSecret(String secret) { |
||||
this.secret = secret; |
||||
} |
||||
|
||||
@Override |
||||
public String xmlTag() { |
||||
return XML_TAG; |
||||
} |
||||
|
||||
@Override |
||||
public void readXML(XMLableReader reader) { |
||||
String tag = reader.getTagName(); |
||||
if( XML_TAG.equals(tag) ){ |
||||
secret = reader.getAttrAsString("secret", StringUtils.EMPTY); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void writeXML(XMLPrintWriter writer) { |
||||
writer.startTAG(XML_TAG).attr("secret",secret).end(); |
||||
} |
||||
|
||||
@Override |
||||
public SpEncryptAttrMark clone() { |
||||
SpEncryptAttrMark obj = (SpEncryptAttrMark)super.clone(); |
||||
obj.secret = secret; |
||||
return obj; |
||||
} |
||||
|
||||
@Override |
||||
public JSONObject createJSONConfig() throws JSONException { |
||||
JSONObject json = super.createJSONConfig(); |
||||
json.put("secret",secret); |
||||
return json; |
||||
} |
||||
} |
Loading…
Reference in new issue