Repository: rememberber/DataSync Branch: master Commit: 622ae9523fc9 Files: 130 Total size: 261.0 KB Directory structure: gitextract_ucn6dq5z/ ├── .travis.yml ├── DB_Backup/ │ ├── Target/ │ │ └── demo_back.sql │ ├── mysql_backup.bat │ └── mysql_table_backup.sql ├── LICENSE.txt ├── TableField/ │ ├── init/ │ │ ├── my_role.DELETE.sql │ │ ├── my_role.INSERT.sql │ │ ├── my_role.UPDATE.sql │ │ ├── my_user.DELETE.sql │ │ ├── my_user.INSERT.sql │ │ └── my_user.UPDATE.sql │ ├── my_role.DELETE.sql │ ├── my_role.INSERT.sql │ ├── my_role.UPDATE.sql │ ├── my_user.DELETE.sql │ ├── my_user.INSERT.sql │ ├── my_user.UPDATE.sql │ └── 公式说明.txt ├── Trigger/ │ └── Trigger.txt ├── _config.yml ├── config/ │ ├── Re-initialization.sql │ ├── config.xml │ ├── databaseBakOriginal.csv │ ├── databaseBakTarget.csv │ └── zh-cn.properties ├── dist/ │ ├── DB_Backup/ │ │ ├── Target/ │ │ │ └── demo_back.sql │ │ ├── mysql_backup.bat │ │ └── mysql_table_backup.sql │ ├── TableField/ │ │ ├── init/ │ │ │ ├── my_role.DELETE.sql │ │ │ ├── my_role.INSERT.sql │ │ │ ├── my_role.UPDATE.sql │ │ │ ├── my_user.DELETE.sql │ │ │ ├── my_user.INSERT.sql │ │ │ └── my_user.UPDATE.sql │ │ ├── my_role.DELETE.sql │ │ ├── my_role.INSERT.sql │ │ ├── my_role.UPDATE.sql │ │ ├── my_user.DELETE.sql │ │ ├── my_user.INSERT.sql │ │ ├── my_user.UPDATE.sql │ │ └── 公式说明.txt │ ├── Trigger/ │ │ └── Trigger.txt │ ├── WeSync-1.0.jar │ ├── WeSync.bat │ ├── config/ │ │ ├── Re-initialization.sql │ │ ├── config.xml │ │ ├── databaseBakOriginal.csv │ │ ├── databaseBakTarget.csv │ │ └── zh-cn.properties │ ├── lib/ │ │ ├── aopalliance-1.0.jar │ │ ├── commons-beanutils-1.9.3.jar │ │ ├── commons-collections-3.2.2.jar │ │ ├── commons-lang3-3.5.jar │ │ ├── commons-logging-1.2.jar │ │ ├── dom4j-2.0.1.jar │ │ ├── emoji-java-3.1.3.jar │ │ ├── jaxen-1.1.6.jar │ │ ├── json-20140107.jar │ │ ├── logback-classic-1.2.1.jar │ │ ├── logback-core-1.2.1.jar │ │ ├── mysql-connector-java-6.0.6.jar │ │ ├── opencsv-3.9.jar │ │ ├── pinyin4j-2.5.1.jar │ │ ├── saxpath-1.0-FCS.jar │ │ ├── slf4j-api-1.7.22.jar │ │ ├── spring-aop-4.3.9.RELEASE.jar │ │ ├── spring-beans-4.3.9.RELEASE.jar │ │ ├── spring-context-4.3.9.RELEASE.jar │ │ ├── spring-core-4.3.9.RELEASE.jar │ │ ├── spring-expression-4.3.9.RELEASE.jar │ │ └── spring-security-core-4.2.3.RELEASE.jar │ ├── snaps/ │ │ ├── role.csv │ │ ├── role_before.csv │ │ ├── user.csv │ │ └── user_before.csv │ └── snaps_bak/ │ ├── role.csv │ ├── role_before.csv │ ├── user.csv │ └── user_before.csv ├── log_SQL/ │ └── log_sql.csv ├── memo.txt ├── pom.xml ├── readme.md ├── snaps/ │ ├── role.csv │ ├── role_before.csv │ ├── user.csv │ └── user_before.csv ├── snaps_bak/ │ ├── role.csv │ ├── role_before.csv │ ├── user.csv │ └── user_before.csv └── src/ └── main/ ├── java/ │ └── com/ │ └── luoboduner/ │ └── wesync/ │ ├── App.java │ ├── logic/ │ │ ├── BackupManage.java │ │ ├── ConstantsLogic.java │ │ ├── ExecuteThread.java │ │ ├── ExecuteThreadInterface.java │ │ ├── ScheduleExecuteThread.java │ │ ├── SnapManage.java │ │ ├── TriggerManage.java │ │ ├── bean/ │ │ │ └── Table.java │ │ └── init/ │ │ └── Init4pxp2p.java │ ├── tools/ │ │ ├── ConfigManager.java │ │ ├── ConstantsTools.java │ │ ├── DESPlus.java │ │ ├── DbUtilMySQL.java │ │ ├── DbUtilSQLServer.java │ │ ├── FileUtils.java │ │ ├── LogLevel.java │ │ ├── PropertyUtil.java │ │ ├── StatusLog.java │ │ ├── Utils.java │ │ └── package-info.java │ └── ui/ │ ├── UiConsts.java │ ├── component/ │ │ └── MyIconButton.java │ ├── dialog/ │ │ └── DbBackUpCreateDialog.java │ └── panel/ │ ├── BackupPanel.java │ ├── DatabasePanel.java │ ├── DatabasePanelFrom.java │ ├── DatabasePanelTo.java │ ├── SchedulePanel.java │ ├── SettingPanel.java │ ├── SettingPanelAbout.java │ ├── SettingPanelOption.java │ ├── StatusPanel.java │ └── ToolBarPanel.java └── resources/ ├── icon/ │ ├── WeSync.psd │ ├── textButton.psd │ ├── textButton206_30.psd │ └── textButton82_30.psd └── logback.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .travis.yml ================================================ language: java jdk: - openjdk8 script: "mvn clean package -Dmaven.test.skip=true" notifications: email: - rememberber@163.com ================================================ FILE: DB_Backup/Target/demo_back.sql ================================================ ================================================ FILE: DB_Backup/mysql_backup.bat ================================================ @echo off & setlocal ENABLEEXTENSIONS set BACKUP_PATH=D:\workspaceWeSync\weSync\DB_Backup\Target set DATABASES=TEST_2017_M set HOST=localhost set USERNAME=root set PASSWORD=123456S set MYSQL=D:\MySQL set path_bin_mysql=%MYSQL%\bin\ set YEAR=%date:~0,4% set MONTH=%date:~5,2% set DAY=%date:~8,2% set HOUR=%time:~0,2% set MINUTE=%time:~3,2% set SECOND=%time:~6,2% set DIR=%BACKUP_PATH% set ADDON="%YEAR%%MONTH%%DAY%_%HOUR%%MINUTE%%SECOND%" if not exist %DIR% ( mkdir %DIR% ) if not exist %DIR% ( echo Backup path: %DIR% not exists, create dir failed. goto exit ) cd /d %DIR% echo Start dump databases... for %%D in (%DATABASES%) do ( echo Dumping database %%D ... %path_bin_mysql%mysqldump -h%HOST% -u%USERNAME% -p%PASSWORD% --skip-lock-tables %%D > %%D_%ADDON%.sql ) echo Done :exit ================================================ FILE: DB_Backup/mysql_table_backup.sql ================================================ drop table if exists table_demo_a_bak; create table table_demo_a_bak like table_demo_a; insert into table_demo_a_bak select * from table_demo_a; drop table if exists table_demo_b_bak; create table table_demo_b_bak like table_demo_b; insert into table_demo_b_bak select * from table_demo_b; drop table if exists table_demo_c_bak; create table table_demo_c_bak like table_demo_c; insert into table_demo_c_bak select * from table_demo_c; ================================================ FILE: LICENSE.txt ================================================ MIT License Copyright (c) [2017] [WeSync] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: TableField/init/my_role.DELETE.sql ================================================ UPDATE my_role SET UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, STATUS = '1' WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: TableField/init/my_role.INSERT.sql ================================================ INSERT INTO my_role ( ROLE_NAME, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, STATUS, REMARK ) VALUES ( 'this.Name', '$SYS_DATE_TIME$', 2, '', 2, '2', '' ); ================================================ FILE: TableField/init/my_role.UPDATE.sql ================================================ UPDATE my_role SET ROLE_NAME = 'this.Name', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: TableField/init/my_user.DELETE.sql ================================================ UPDATE my_user SET STATUS = '1', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: TableField/init/my_user.INSERT.sql ================================================ INSERT INTO my_user ( LOGIN_NAME, PASSWORD, REAL_NAME, STATUS, ADDRESS, RMK, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, LOGIN_IP, MOBILE, SYS_EMAIL, TELPHONE, LOGO_IMG, PROVINCE, CITY, sbc_id, EMP_CODE, ID_CARD, DEPT_CODE, POSITION_CODE, BANK_NUMBER ) VALUES ( '$PINYIN{this.Name}$@SUB(7,END){this.Telphone}@', '#MD5PE{@SUB(12,END){this.IDCardID}@}#', 'this.Name', '#CASE(1=2,2=1){this.Status}#', 'this.Address', '', '$SYS_DATE_TIME$', 2, '', null, '', 'this.Telphone', 'this.EMail', '', '', '', '', null, '', 'this.IDCardID', left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), 'this.BankAccountNum' ); INSERT INTO my_user_role ( USER_ID, ROLE_ID, STATUS, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, REMARK ) VALUES ( (SELECT MAX(ID) FROM my_user), (SELECT ID FROM my_role WHERE ROLE_NAME = 'test'), '2', '$SYS_DATE_TIME$', 2, '', null, null ); ================================================ FILE: TableField/init/my_user.UPDATE.sql ================================================ UPDATE my_user SET REAL_NAME = 'this.Name', ADDRESS = 'this.Address', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, MOBILE = 'this.Telphone', SYS_EMAIL = 'this.EMail', ID_CARD = 'this.IDCardID', DEPT_CODE = left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), POSITION_CODE = (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), BANK_NUMBER = 'this.BankAccountNum' WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: TableField/my_role.DELETE.sql ================================================ UPDATE my_role SET UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, STATUS = '1' WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: TableField/my_role.INSERT.sql ================================================ INSERT INTO my_role ( ROLE_NAME, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, STATUS, REMARK ) VALUES ( 'this.Name', '$SYS_DATE_TIME$', 2, '', 2, '2', '' ); ================================================ FILE: TableField/my_role.UPDATE.sql ================================================ UPDATE my_role SET ROLE_NAME = 'this.Name', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: TableField/my_user.DELETE.sql ================================================ UPDATE my_user SET STATUS = '1', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: TableField/my_user.INSERT.sql ================================================ INSERT INTO my_user ( LOGIN_NAME, PASSWORD, REAL_NAME, STATUS, ADDRESS, RMK, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, LOGIN_IP, MOBILE, SYS_EMAIL, TELPHONE, LOGO_IMG, PROVINCE, CITY, sbc_id, EMP_CODE, ID_CARD, DEPT_CODE, POSITION_CODE, BANK_NUMBER ) VALUES ( '$PINYIN{this.Name}$@SUB(7,END){this.Telphone}@', '#MD5PE{@SUB(12,END){this.IDCardID}@}#', 'this.Name', '#CASE(1=2,2=1){this.Status}#', 'this.Address', '', '$SYS_DATE_TIME$', 2, '', null, '', 'this.Telphone', 'this.EMail', '', '', '', '', null, '', 'this.IDCardID', left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), 'this.BankAccountNum' ); INSERT INTO my_user_role ( USER_ID, ROLE_ID, STATUS, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, REMARK ) VALUES ( (SELECT MAX(ID) FROM my_user), (SELECT ID FROM my_role WHERE ROLE_NAME = 'test'), '2', '$SYS_DATE_TIME$', 2, '', null, null ); ================================================ FILE: TableField/my_user.UPDATE.sql ================================================ UPDATE my_user SET REAL_NAME = 'this.Name', ADDRESS = 'this.Address', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, MOBILE = 'this.Telphone', SYS_EMAIL = 'this.EMail', ID_CARD = 'this.IDCardID', DEPT_CODE = left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), POSITION_CODE = (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), BANK_NUMBER = 'this.BankAccountNum' WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: TableField/公式说明.txt ================================================ 注意:同级别公式暂不支持嵌套! 第一级别公式: this.***:取当前快照该条记录的某字段值 before.***:取原快照该条记录的某字段值(仅UPDATE和DELETE时会用到) 第二级别公式: $INCREASE{POSITION_CODE}$:将大括号内的持久化变量递增(*在config文件中设置持久化变量) $PINYIN{}$:将大括号内的汉字转为拼音 $SYS_DATE_TIME$:系统日期+时间(2016-01-19 17:57:49) $SQL{}$:执行大括号内的子查询sql,返回对应的查询结果(仅限一个) 第三级别公式: @SUB(5,8){}@:将大括号内的字符串从第5个字符截取到第8个字符(同java的substring方法,含左不含右) @SUB(5,END){}@:将大括号内的字符串从第5个字符截取到最后(同java的substring方法,含左不含右) @SUB(0,LAST"."){}@:将大括号内的字符串从第0个字符截取到最后一个"."(同java的substring方法,含左不含右) @SUB("a",LAST"a"){}@:将大括号内的字符串从第1个"a"截取到最后一个"a"(不含左不含右) 第四级别公式: #REPLACE("a","b"){}#:将大括号内容中所有的"a"替换为"b" #CASE(a=b,c=d,e=f){}#:如果大括号里边的内容是a,则替换为b;如果为c,则替换为d... #MD5PE{}#:将大括号内的密码字符串进行Md5PasswordEncoder的encodePassword处理 ================================================ FILE: Trigger/Trigger.txt ================================================ // 规则:快照名:<来源表>(主键){字段}[其他条件]=<目标表1>(主键){字段}[保留]=<目标表2>(主键){字段}[保留]... // 多个以英文逗号隔开 // 注意:]=<等符号旁边不要有空格 // 示例:Snap_tableA:(id){id,name,other}[WHERE status = '1' ORDER BY id]=(id){id,real_name,password} role:(Name){Name}[WHERE IsDelete = 0 GROUP BY Name ORDER BY Name]=(ID){ID,ROLE_NAME,CREATE_DATE,CREATE_USER,UPDATE_DATE,UPDATE_USER,STATUS,REMARK}[] user:(id){u.id,u.Name,u.IDCardID,u.Telphone,u.Address,u.EMail,u.Status}[WHERE u.Status = 1 and u.IDCardID is not null and u.IDCardID != '' ORDER BY u.id]=(ID){ID,LOGIN_NAME,PASSWORD,REAL_NAME,STATUS,ADDRESS,RMK,CREATE_DATE,CREATE_USER,UPDATE_DATE,UPDATE_USER,LOGIN_IP,MOBILE,SYS_EMAIL,TELPHONE,LOGO_IMG,PROVINCE,CITY,sbc_id,EMP_CODE,ID_CARD,DEPT_CODE,POSITION_CODE,BANK_NUMBER}[] ================================================ FILE: _config.yml ================================================ theme: jekyll-theme-cayman ================================================ FILE: config/Re-initialization.sql ================================================ -- 还原普相关表到初始化状态 -- 这里相当于一个备忘录,记录和保存你日常经常执行的一些还原操作的sql ================================================ FILE: config/config.xml ================================================ 2016-05-27 09:53:00 10.125 35 9 SQL Server 127.0.0.1 TEST_2017 MySQL localhost TEST_2017_M false,false,false,false,false,false,true 23:45:00 true false false D:\MySQL 产品A,产品B 0 ================================================ FILE: config/databaseBakOriginal.csv ================================================ ================================================ FILE: config/databaseBakTarget.csv ================================================ ================================================ FILE: config/zh-cn.properties ================================================ ds.ui.sure=\u786E\u5B9A ds.ui.cancel=\u53D6\u6D88 ds.ui.save.success=\u4FDD\u5B58\u6210\u529F\uFF01 ds.ui.save.fail=\u4FDD\u5B58\u5931\u8D25\uFF01\n ds.ui.tips=\u63D0\u793A ds.ui.font.family=\u5FAE\u8F6F\u96C5\u9ED1 ds.ui.mainwindow.exitconfirm=\u4E3A\u907F\u514D\u4E0D\u5FC5\u8981\u7684\u4EFB\u52A1\u5931\u8D25\n\u5DF2\u963B\u6B62\u60A8\u5173\u95ED\u8BE5\u7A0B\u5E8F\uFF01\n\u5982\u9700\u9000\u51FA\uFF0C\u8BF7\u5148\u505C\u6B62\u4EFB\u52A1\uFF01 ds.ui.mainwindow.dialog.newBackUp=\u65B0\u5EFA\u5907\u4EFD ds.ui.mainwindow.dialog.type=\u7C7B\u578B\uFF1A ds.ui.mainwindow.dialog.remarks=\u5907\u6CE8\uFF1A ds.ui.mainwindow.dialog.progress=\u8FDB\u5EA6\uFF1A ds.ui.mainwindow.dialog.comboxType0=\u6765\u6E90\u6570\u636E\u5E93\u6574\u5E93\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType1=\u6765\u6E90\u8868\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType2=\u76EE\u6807\u6570\u636E\u5E93\u6574\u5E93\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType3=\u76EE\u6807\u8868\u5907\u4EFD ds.ui.app.advice=\u53CD\u9988\u5EFA\u8BAE ds.ui.app.help=\u5E2E\u52A9 ds.ui.app.info=Copyright 2016 | All Rights Reserved.\u5468\u6CE2\u4E2D\u56FD | www.zhoubochina.com ds.ui.status.title=\u72B6\u6001 ds.ui.database.title=\u6570\u636E\u5E93\u8BBE\u7F6E ds.ui.schedule.title=\u4EFB\u52A1\u8BA1\u5212 ds.ui.backup.title=\u5907\u4EFD\u7BA1\u7406 ds.ui.setting.title=\u8BBE\u7F6E ds.ui.backup.table.head0=\u5E8F\u53F7 ds.ui.backup.table.head1=\u540D\u79F0 ds.ui.backup.table.head2=\u5927\u5C0F ds.ui.database.label.from=\u6765\u6E90\u6570\u636E\u5E93 ds.ui.database.label.to=\u76EE\u6807\u6570\u636E\u5E93 ds.ui.database.type=\u6570\u636E\u5E93\u7C7B\u578B\uFF1A ds.ui.database.host=\u6570\u636E\u5E93\u5730\u5740\uFF1A ds.ui.database.name=\u6570\u636E\u5E93\u540D\u79F0\uFF1A ds.ui.database.user=\u7528\u6237\u540D\uFF1A ds.ui.database.password=\u5BC6\u7801\uFF1A ds.ui.database.from.err.decode=\u6765\u6E90\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u89E3\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.from.err.encode=\u6765\u6E90\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u52A0\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.err.link.fail=\u8FDE\u63A5\u5931\u8D25\uFF01 ds.ui.database.err.link.success=\u8FDE\u63A5\u6210\u529F\uFF01 ds.ui.database.to.err.decode=\u76EE\u6807\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u89E3\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.to.err.encode=\u76EE\u6807\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u52A0\u5BC6\u9519\u8BEF\uFF1A ds.ui.schedule.radio1=5\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio2=15\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio3=30\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio4=\u6BCF\u5C0F\u65F6\u4E00\u6B21 ds.ui.schedule.radio5=\u6BCF\u5929\u4E00\u6B21 ds.ui.schedule.radio6=\u6BCF\u5468\u4E00\u6B21 ds.ui.schedule.radio7=\u6BCF\u5929\u6309\u56FA\u5B9A\u65F6\u95F4\u6267\u884C(hh:mm:ss)\uFF1A ds.ui.schedule.saveTips=\u4FDD\u5B58\u6210\u529F\uFF01\n\n\u5C06\u5728\u4E0B\u6B21\u4EFB\u52A1\u65F6\u751F\u6548\n\u5982\u6B63\u5728\u6267\u884C\u8BA1\u5212\u4EFB\u52A1\uFF0C\u8BF7\u624B\u52A8\u505C\u6B62\u5E76\u91CD\u65B0\u542F\u52A8\u8BA1\u5212\u4EFB\u52A1\n ds.ui.schedule.nextTime=\u4E0B\u4E00\u6B21\u540C\u6B65\u65F6\u95F4\uFF1A ds.ui.setting.option=\u9AD8\u7EA7\u9009\u9879 ds.ui.setting.about=\u5173\u4E8E ds.ui.setting.autoBackUp=\u81EA\u52A8\u5907\u4EFD ds.ui.setting.mysqlPath=MySQL\u5B89\u88C5\u8DEF\u5F84: ds.ui.setting.strict=\u4E25\u683C\u6A21\u5F0F ds.ui.setting.debugMode=\u5F00\u53D1\u8005\u8C03\u8BD5\u6A21\u5F0F ds.ui.setting.clean.makeSure=\u786E\u5B9A\u6E05\u7A7A\u5417\uFF1F ds.ui.setting.clean.success=\u6E05\u7A7A\u6210\u529F\uFF01 ds.ui.setting.clean.fail=\u6E05\u7A7A\u5931\u8D25\uFF01\n ds.ui.status.ready=\u5C31\u7EEA ds.ui.status.detail=\u8BE6\u60C5\uFF1A\u5C31\u7EEA ds.ui.status.logDetail=\u67E5\u770B\u8BE6\u7EC6\u65E5\u5FD7 ds.ui.status.progress.current=\u5F53\u524D\u8FDB\u5EA6\uFF1A ds.ui.status.progress.total=\u672C\u6B21\u603B\u8FDB\u5EA6\uFF1A ds.ui.status.from=\u6765\u6E90\uFF1ASQL Server/ ds.ui.status.to=\u76EE\u6807\uFF1AMySQL/ ds.ui.status.lastSync=\u4E0A\u4E00\u6B21\u540C\u6B65\u65F6\u95F4\uFF1A ds.ui.status.keepTime=\u6301\u7EED\u65F6\u95F4\uFF1A ds.ui.status.second=\u79D2 ds.ui.status.successTimes=\u6210\u529F\u603B\u6B21\u6570 ds.ui.status.failTimes=\u5931\u8D25\u603B\u6B21\u6570\uFF1A ds.ui.status.manu=\u624B\u52A8\u540C\u6B65\u6267\u884C\u4E2D\u2026\u2026 ds.ui.status.scheduledRunning=\u6309\u8BA1\u5212\u6267\u884C\u4E2D\u2026\u2026 ds.tool.detail=\u8BE6\u60C5\uFF1A ds.com.luoboduner.wesync.logic.backuping=\u6B63\u5728\u5907\u4EFDMySQL\u6570\u636E\u5E93\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85\u2026\u2026 ds.com.luoboduner.wesync.logic.backupTable=\u6B63\u5728\u5907\u4EFDMySQL\u6570\u636E\u5E93\u76F8\u5173\u8868\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85: ds.com.luoboduner.wesync.logic.testLinking=\u5F00\u59CB\u6D4B\u8BD5\u8FDE\u63A5 ds.com.luoboduner.wesync.logic.testLinkFail=\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.testLinkFinish=\u8FDE\u63A5\u6D4B\u8BD5\u7ED3\u675F ds.com.luoboduner.wesync.logic.startAnalyse=\u5F00\u59CB\u89E3\u6790\u914D\u7F6E\u6587\u4EF6 ds.com.luoboduner.wesync.logic.AnalyseFail=\u89E3\u6790\u8868-\u5B57\u6BB5\u914D\u7F6Esql\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.AnalyseTriggerFail=\u89E3\u6790Trigger\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.finishAnalyse=\u914D\u7F6E\u6587\u4EF6\u89E3\u6790\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startBackUp=\u5F00\u59CB\u5907\u4EFD ds.com.luoboduner.wesync.logic.finishBackUp=\u5907\u4EFD\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startNewSnap=\u5F00\u59CB\u65B0\u5EFA\u5FEB\u7167 ds.com.luoboduner.wesync.logic.finishNewSnap=\u65B0\u5FEB\u7167\u5EFA\u7ACB\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startDiffSnap=\u5F00\u59CB\u5BF9\u6BD4\u5FEB\u7167 ds.com.luoboduner.wesync.logic.finishDiffSnap=\u5BF9\u6BD4\u5FEB\u7167\u5B8C\u6210 ds.com.luoboduner.wesync.logic.diffSnapFail=\u5BF9\u6BD4\u5FEB\u7167\u5931\u8D25 ds.com.luoboduner.wesync.logic.startRunSql=\u5F00\u59CB\u6267\u884CSQL ds.com.luoboduner.wesync.logic.runSqlFail=SQL\u6267\u884C\u5931\u8D25\uFF0C\u7531\u4E8E\u5176\u4E2D\u67D0\u4E9BSQL\u5F71\u54CD\u591A\u884C\uFF0C\u5DF2\u7ECF\u56DE\u6EDA\u4E8B\u52A1 ds.com.luoboduner.wesync.logic.runSqlFinish=SQL\u6267\u884C\u5B8C\u6210 ds.com.luoboduner.wesync.logic.syncFinish=\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSqlFail=->\u6267\u884CSQL\u5931\u8D25: ds.com.luoboduner.wesync.logic.runScheduleing=\u6309\u8BA1\u5212\u6267\u884C\u4E2D\u2026\u2026 ds.com.luoboduner.wesync.logic.manuSyncFinish=\u624B\u52A8\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentManuSyncFinish=\u672C\u6B21\u624B\u52A8\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSyncFinish=\u672C\u6B21\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSnapDirBackFail=\u5907\u4EFD\u5F53\u524D\u5FEB\u7167\u6587\u4EF6\u5939\u5931\u8D25 ds.com.luoboduner.wesync.logic.ifLastSnapExistFail=\u5224\u65AD\u4E0A\u4E00\u6B21\u7684\u5FEB\u7167\u662F\u5426\u5B58\u5728\u5931\u8D25 ds.com.luoboduner.wesync.logic.newSnapFileFail=\u65B0\u5FEB\u7167\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.beforeSnapMd5Fail=\u83B7\u53D6\u539F\u5FEB\u7167MD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.nowSnapMd5Fail=\u83B7\u53D6\u65B0\u5FEB\u7167MD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.lineByLineDiffFail=\u9010\u884C\u5BF9\u6BD4\u5FEB\u7167csv\u5931\u8D25 ds.com.luoboduner.wesync.logic.restoreSnapBackFail=\u6062\u590D\u5FEB\u7167\u5907\u4EFD\u5931\u8D25\uFF1A ds.com.luoboduner.wesync.logic.tableChanged=:\u65B0\u5FEB\u7167\u4E0E\u539F\u5FEB\u7167\u8868\u5934\u4E0D\u4E00\u81F4\uFF0C\u8003\u8651\u8868\u7ED3\u6784\u662F\u5426\u5DF2\u7ECF\u53D8\u66F4\uFF1F ================================================ FILE: dist/DB_Backup/Target/demo_back.sql ================================================ ================================================ FILE: dist/DB_Backup/mysql_backup.bat ================================================ @echo off & setlocal ENABLEEXTENSIONS set BACKUP_PATH=D:\workspaceWeSync\weSync\DB_Backup\Target set DATABASES=TEST_2017_M set HOST=localhost set USERNAME=root set PASSWORD=123456S set MYSQL=D:\MySQL set path_bin_mysql=%MYSQL%\bin\ set YEAR=%date:~0,4% set MONTH=%date:~5,2% set DAY=%date:~8,2% set HOUR=%time:~0,2% set MINUTE=%time:~3,2% set SECOND=%time:~6,2% set DIR=%BACKUP_PATH% set ADDON="%YEAR%%MONTH%%DAY%_%HOUR%%MINUTE%%SECOND%" if not exist %DIR% ( mkdir %DIR% ) if not exist %DIR% ( echo Backup path: %DIR% not exists, create dir failed. goto exit ) cd /d %DIR% echo Start dump databases... for %%D in (%DATABASES%) do ( echo Dumping database %%D ... %path_bin_mysql%mysqldump -h%HOST% -u%USERNAME% -p%PASSWORD% --skip-lock-tables %%D > %%D_%ADDON%.sql ) echo Done :exit ================================================ FILE: dist/DB_Backup/mysql_table_backup.sql ================================================ drop table if exists table_demo_a_bak; create table table_demo_a_bak like table_demo_a; insert into table_demo_a_bak select * from table_demo_a; drop table if exists table_demo_b_bak; create table table_demo_b_bak like table_demo_b; insert into table_demo_b_bak select * from table_demo_b; drop table if exists table_demo_c_bak; create table table_demo_c_bak like table_demo_c; insert into table_demo_c_bak select * from table_demo_c; ================================================ FILE: dist/TableField/init/my_role.DELETE.sql ================================================ UPDATE my_role SET UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, STATUS = '1' WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: dist/TableField/init/my_role.INSERT.sql ================================================ INSERT INTO my_role ( ROLE_NAME, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, STATUS, REMARK ) VALUES ( 'this.Name', '$SYS_DATE_TIME$', 2, '', 2, '2', '' ); ================================================ FILE: dist/TableField/init/my_role.UPDATE.sql ================================================ UPDATE my_role SET ROLE_NAME = 'this.Name', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: dist/TableField/init/my_user.DELETE.sql ================================================ UPDATE my_user SET STATUS = '1', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: dist/TableField/init/my_user.INSERT.sql ================================================ INSERT INTO my_user ( LOGIN_NAME, PASSWORD, REAL_NAME, STATUS, ADDRESS, RMK, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, LOGIN_IP, MOBILE, SYS_EMAIL, TELPHONE, LOGO_IMG, PROVINCE, CITY, sbc_id, EMP_CODE, ID_CARD, DEPT_CODE, POSITION_CODE, BANK_NUMBER ) VALUES ( '$PINYIN{this.Name}$@SUB(7,END){this.Telphone}@', '#MD5PE{@SUB(12,END){this.IDCardID}@}#', 'this.Name', '#CASE(1=2,2=1){this.Status}#', 'this.Address', '', '$SYS_DATE_TIME$', 2, '', null, '', 'this.Telphone', 'this.EMail', '', '', '', '', null, '', 'this.IDCardID', left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), 'this.BankAccountNum' ); INSERT INTO my_user_role ( USER_ID, ROLE_ID, STATUS, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, REMARK ) VALUES ( (SELECT MAX(ID) FROM my_user), (SELECT ID FROM my_role WHERE ROLE_NAME = 'test'), '2', '$SYS_DATE_TIME$', 2, '', null, null ); ================================================ FILE: dist/TableField/init/my_user.UPDATE.sql ================================================ UPDATE my_user SET REAL_NAME = 'this.Name', ADDRESS = 'this.Address', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, MOBILE = 'this.Telphone', SYS_EMAIL = 'this.EMail', ID_CARD = 'this.IDCardID', DEPT_CODE = left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), POSITION_CODE = (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), BANK_NUMBER = 'this.BankAccountNum' WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: dist/TableField/my_role.DELETE.sql ================================================ UPDATE my_role SET UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, STATUS = '1' WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: dist/TableField/my_role.INSERT.sql ================================================ INSERT INTO my_role ( ROLE_NAME, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, STATUS, REMARK ) VALUES ( 'this.Name', '$SYS_DATE_TIME$', 2, '', 2, '2', '' ); ================================================ FILE: dist/TableField/my_role.UPDATE.sql ================================================ UPDATE my_role SET ROLE_NAME = 'this.Name', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE (ROLE_NAME = 'before.Name'); ================================================ FILE: dist/TableField/my_user.DELETE.sql ================================================ UPDATE my_user SET STATUS = '1', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2 WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: dist/TableField/my_user.INSERT.sql ================================================ INSERT INTO my_user ( LOGIN_NAME, PASSWORD, REAL_NAME, STATUS, ADDRESS, RMK, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, LOGIN_IP, MOBILE, SYS_EMAIL, TELPHONE, LOGO_IMG, PROVINCE, CITY, sbc_id, EMP_CODE, ID_CARD, DEPT_CODE, POSITION_CODE, BANK_NUMBER ) VALUES ( '$PINYIN{this.Name}$@SUB(7,END){this.Telphone}@', '#MD5PE{@SUB(12,END){this.IDCardID}@}#', 'this.Name', '#CASE(1=2,2=1){this.Status}#', 'this.Address', '', '$SYS_DATE_TIME$', 2, '', null, '', 'this.Telphone', 'this.EMail', '', '', '', '', null, '', 'this.IDCardID', left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), 'this.BankAccountNum' ); INSERT INTO my_user_role ( USER_ID, ROLE_ID, STATUS, CREATE_DATE, CREATE_USER, UPDATE_DATE, UPDATE_USER, REMARK ) VALUES ( (SELECT MAX(ID) FROM my_user), (SELECT ID FROM my_role WHERE ROLE_NAME = 'test'), '2', '$SYS_DATE_TIME$', 2, '', null, null ); ================================================ FILE: dist/TableField/my_user.UPDATE.sql ================================================ UPDATE my_user SET REAL_NAME = 'this.Name', ADDRESS = 'this.Address', UPDATE_DATE = '$SYS_DATE_TIME$', UPDATE_USER = 2, MOBILE = 'this.Telphone', SYS_EMAIL = 'this.EMail', ID_CARD = 'this.IDCardID', DEPT_CODE = left('#REPLACE(".",""){@SUB(".",END){this.UnitCode}@}#',16), POSITION_CODE = (SELECT SP_POSITION_CODE FROM my_position WHERE SP_POSITION_NAME = '$SQL{SELECT PositionName FROM Info WHERE id = 'this.id'}$'), BANK_NUMBER = 'this.BankAccountNum' WHERE ID_CARD = 'before.IDCardID' ; ================================================ FILE: dist/TableField/公式说明.txt ================================================ 注意:同级别公式暂不支持嵌套! 第一级别公式: this.***:取当前快照该条记录的某字段值 before.***:取原快照该条记录的某字段值(仅UPDATE和DELETE时会用到) 第二级别公式: $INCREASE{POSITION_CODE}$:将大括号内的持久化变量递增(*在config文件中设置持久化变量) $PINYIN{}$:将大括号内的汉字转为拼音 $SYS_DATE_TIME$:系统日期+时间(2016-01-19 17:57:49) $SQL{}$:执行大括号内的子查询sql,返回对应的查询结果(仅限一个) 第三级别公式: @SUB(5,8){}@:将大括号内的字符串从第5个字符截取到第8个字符(同java的substring方法,含左不含右) @SUB(5,END){}@:将大括号内的字符串从第5个字符截取到最后(同java的substring方法,含左不含右) @SUB(0,LAST"."){}@:将大括号内的字符串从第0个字符截取到最后一个"."(同java的substring方法,含左不含右) @SUB("a",LAST"a"){}@:将大括号内的字符串从第1个"a"截取到最后一个"a"(不含左不含右) 第四级别公式: #REPLACE("a","b"){}#:将大括号内容中所有的"a"替换为"b" #CASE(a=b,c=d,e=f){}#:如果大括号里边的内容是a,则替换为b;如果为c,则替换为d... #MD5PE{}#:将大括号内的密码字符串进行Md5PasswordEncoder的encodePassword处理 ================================================ FILE: dist/Trigger/Trigger.txt ================================================ // 规则:快照名:<来源表>(主键){字段}[其他条件]=<目标表1>(主键){字段}[保留]=<目标表2>(主键){字段}[保留]... // 多个以英文逗号隔开 // 注意:]=<等符号旁边不要有空格 // 示例:Snap_tableA:(id){id,name,other}[WHERE status = '1' ORDER BY id]=(id){id,real_name,password} role:(Name){Name}[WHERE IsDelete = 0 GROUP BY Name ORDER BY Name]=(ID){ID,ROLE_NAME,CREATE_DATE,CREATE_USER,UPDATE_DATE,UPDATE_USER,STATUS,REMARK}[] user:(id){u.id,u.Name,u.IDCardID,u.Telphone,u.Address,u.EMail,u.Status}[WHERE u.Status = 1 and u.IDCardID is not null and u.IDCardID != '' ORDER BY u.id]=(ID){ID,LOGIN_NAME,PASSWORD,REAL_NAME,STATUS,ADDRESS,RMK,CREATE_DATE,CREATE_USER,UPDATE_DATE,UPDATE_USER,LOGIN_IP,MOBILE,SYS_EMAIL,TELPHONE,LOGO_IMG,PROVINCE,CITY,sbc_id,EMP_CODE,ID_CARD,DEPT_CODE,POSITION_CODE,BANK_NUMBER}[] ================================================ FILE: dist/WeSync.bat ================================================ start javaw -jar WeSync-1.0.jar ================================================ FILE: dist/config/Re-initialization.sql ================================================ -- 还原普相关表到初始化状态 -- 这里相当于一个备忘录,记录和保存你日常经常执行的一些还原操作的sql ================================================ FILE: dist/config/config.xml ================================================ 2016-05-27 09:53:00 10.125 35 9 SQL Server 127.0.0.1 TEST_2017 97da459ae523ae80 1ca6dbffc8f125b4 MySQL localhost TEST_2017_M 9bc42c9884cdbe3e 1ca6dbffc8f125b4 false,false,false,false,false,false,true 23:45:00 true false false D:\MySQL 产品A,产品B 0 ================================================ FILE: dist/config/databaseBakOriginal.csv ================================================ ================================================ FILE: dist/config/databaseBakTarget.csv ================================================ ================================================ FILE: dist/config/zh-cn.properties ================================================ ds.ui.sure=\u786E\u5B9A ds.ui.cancel=\u53D6\u6D88 ds.ui.save.success=\u4FDD\u5B58\u6210\u529F\uFF01 ds.ui.save.fail=\u4FDD\u5B58\u5931\u8D25\uFF01\n ds.ui.tips=\u63D0\u793A ds.ui.font.family=\u5FAE\u8F6F\u96C5\u9ED1 ds.ui.mainwindow.exitconfirm=\u4E3A\u907F\u514D\u4E0D\u5FC5\u8981\u7684\u4EFB\u52A1\u5931\u8D25\n\u5DF2\u963B\u6B62\u60A8\u5173\u95ED\u8BE5\u7A0B\u5E8F\uFF01\n\u5982\u9700\u9000\u51FA\uFF0C\u8BF7\u5148\u505C\u6B62\u4EFB\u52A1\uFF01 ds.ui.mainwindow.dialog.newBackUp=\u65B0\u5EFA\u5907\u4EFD ds.ui.mainwindow.dialog.type=\u7C7B\u578B\uFF1A ds.ui.mainwindow.dialog.remarks=\u5907\u6CE8\uFF1A ds.ui.mainwindow.dialog.progress=\u8FDB\u5EA6\uFF1A ds.ui.mainwindow.dialog.comboxType0=\u6765\u6E90\u6570\u636E\u5E93\u6574\u5E93\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType1=\u6765\u6E90\u8868\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType2=\u76EE\u6807\u6570\u636E\u5E93\u6574\u5E93\u5907\u4EFD ds.ui.mainwindow.dialog.comboxType3=\u76EE\u6807\u8868\u5907\u4EFD ds.ui.app.advice=\u53CD\u9988\u5EFA\u8BAE ds.ui.app.help=\u5E2E\u52A9 ds.ui.app.info=Copyright 2016 | All Rights Reserved.\u5468\u6CE2\u4E2D\u56FD | www.zhoubochina.com ds.ui.status.title=\u72B6\u6001 ds.ui.database.title=\u6570\u636E\u5E93\u8BBE\u7F6E ds.ui.schedule.title=\u4EFB\u52A1\u8BA1\u5212 ds.ui.backup.title=\u5907\u4EFD\u7BA1\u7406 ds.ui.setting.title=\u8BBE\u7F6E ds.ui.backup.table.head0=\u5E8F\u53F7 ds.ui.backup.table.head1=\u540D\u79F0 ds.ui.backup.table.head2=\u5927\u5C0F ds.ui.database.label.from=\u6765\u6E90\u6570\u636E\u5E93 ds.ui.database.label.to=\u76EE\u6807\u6570\u636E\u5E93 ds.ui.database.type=\u6570\u636E\u5E93\u7C7B\u578B\uFF1A ds.ui.database.host=\u6570\u636E\u5E93\u5730\u5740\uFF1A ds.ui.database.name=\u6570\u636E\u5E93\u540D\u79F0\uFF1A ds.ui.database.user=\u7528\u6237\u540D\uFF1A ds.ui.database.password=\u5BC6\u7801\uFF1A ds.ui.database.from.err.decode=\u6765\u6E90\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u89E3\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.from.err.encode=\u6765\u6E90\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u52A0\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.err.link.fail=\u8FDE\u63A5\u5931\u8D25\uFF01 ds.ui.database.err.link.success=\u8FDE\u63A5\u6210\u529F\uFF01 ds.ui.database.to.err.decode=\u76EE\u6807\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u89E3\u5BC6\u9519\u8BEF\uFF1A ds.ui.database.to.err.encode=\u76EE\u6807\u6570\u636E\u5E93\u7528\u6237\u540D\u6216\u5BC6\u7801\u52A0\u5BC6\u9519\u8BEF\uFF1A ds.ui.schedule.radio1=5\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio2=15\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio3=30\u5206\u949F\u4E00\u6B21 ds.ui.schedule.radio4=\u6BCF\u5C0F\u65F6\u4E00\u6B21 ds.ui.schedule.radio5=\u6BCF\u5929\u4E00\u6B21 ds.ui.schedule.radio6=\u6BCF\u5468\u4E00\u6B21 ds.ui.schedule.radio7=\u6BCF\u5929\u6309\u56FA\u5B9A\u65F6\u95F4\u6267\u884C(hh:mm:ss)\uFF1A ds.ui.schedule.saveTips=\u4FDD\u5B58\u6210\u529F\uFF01\n\n\u5C06\u5728\u4E0B\u6B21\u4EFB\u52A1\u65F6\u751F\u6548\n\u5982\u6B63\u5728\u6267\u884C\u8BA1\u5212\u4EFB\u52A1\uFF0C\u8BF7\u624B\u52A8\u505C\u6B62\u5E76\u91CD\u65B0\u542F\u52A8\u8BA1\u5212\u4EFB\u52A1\n ds.ui.schedule.nextTime=\u4E0B\u4E00\u6B21\u540C\u6B65\u65F6\u95F4\uFF1A ds.ui.setting.option=\u9AD8\u7EA7\u9009\u9879 ds.ui.setting.about=\u5173\u4E8E ds.ui.setting.autoBackUp=\u81EA\u52A8\u5907\u4EFD ds.ui.setting.mysqlPath=MySQL\u5B89\u88C5\u8DEF\u5F84: ds.ui.setting.strict=\u4E25\u683C\u6A21\u5F0F ds.ui.setting.debugMode=\u5F00\u53D1\u8005\u8C03\u8BD5\u6A21\u5F0F ds.ui.setting.clean.makeSure=\u786E\u5B9A\u6E05\u7A7A\u5417\uFF1F ds.ui.setting.clean.success=\u6E05\u7A7A\u6210\u529F\uFF01 ds.ui.setting.clean.fail=\u6E05\u7A7A\u5931\u8D25\uFF01\n ds.ui.status.ready=\u5C31\u7EEA ds.ui.status.detail=\u8BE6\u60C5\uFF1A\u5C31\u7EEA ds.ui.status.logDetail=\u67E5\u770B\u8BE6\u7EC6\u65E5\u5FD7 ds.ui.status.progress.current=\u5F53\u524D\u8FDB\u5EA6\uFF1A ds.ui.status.progress.total=\u672C\u6B21\u603B\u8FDB\u5EA6\uFF1A ds.ui.status.from=\u6765\u6E90\uFF1ASQL Server/ ds.ui.status.to=\u76EE\u6807\uFF1AMySQL/ ds.ui.status.lastSync=\u4E0A\u4E00\u6B21\u540C\u6B65\u65F6\u95F4\uFF1A ds.ui.status.keepTime=\u6301\u7EED\u65F6\u95F4\uFF1A ds.ui.status.second=\u79D2 ds.ui.status.successTimes=\u6210\u529F\u603B\u6B21\u6570 ds.ui.status.failTimes=\u5931\u8D25\u603B\u6B21\u6570\uFF1A ds.ui.status.manu=\u624B\u52A8\u540C\u6B65\u6267\u884C\u4E2D\u2026\u2026 ds.ui.status.scheduledRunning=\u6309\u8BA1\u5212\u6267\u884C\u4E2D\u2026\u2026 ds.tool.detail=\u8BE6\u60C5\uFF1A ds.com.luoboduner.wesync.logic.backuping=\u6B63\u5728\u5907\u4EFDMySQL\u6570\u636E\u5E93\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85\u2026\u2026 ds.com.luoboduner.wesync.logic.backupTable=\u6B63\u5728\u5907\u4EFDMySQL\u6570\u636E\u5E93\u76F8\u5173\u8868\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85: ds.com.luoboduner.wesync.logic.testLinking=\u5F00\u59CB\u6D4B\u8BD5\u8FDE\u63A5 ds.com.luoboduner.wesync.logic.testLinkFail=\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.testLinkFinish=\u8FDE\u63A5\u6D4B\u8BD5\u7ED3\u675F ds.com.luoboduner.wesync.logic.startAnalyse=\u5F00\u59CB\u89E3\u6790\u914D\u7F6E\u6587\u4EF6 ds.com.luoboduner.wesync.logic.AnalyseFail=\u89E3\u6790\u8868-\u5B57\u6BB5\u914D\u7F6Esql\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.AnalyseTriggerFail=\u89E3\u6790Trigger\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.finishAnalyse=\u914D\u7F6E\u6587\u4EF6\u89E3\u6790\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startBackUp=\u5F00\u59CB\u5907\u4EFD ds.com.luoboduner.wesync.logic.finishBackUp=\u5907\u4EFD\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startNewSnap=\u5F00\u59CB\u65B0\u5EFA\u5FEB\u7167 ds.com.luoboduner.wesync.logic.finishNewSnap=\u65B0\u5FEB\u7167\u5EFA\u7ACB\u5B8C\u6210 ds.com.luoboduner.wesync.logic.startDiffSnap=\u5F00\u59CB\u5BF9\u6BD4\u5FEB\u7167 ds.com.luoboduner.wesync.logic.finishDiffSnap=\u5BF9\u6BD4\u5FEB\u7167\u5B8C\u6210 ds.com.luoboduner.wesync.logic.diffSnapFail=\u5BF9\u6BD4\u5FEB\u7167\u5931\u8D25 ds.com.luoboduner.wesync.logic.startRunSql=\u5F00\u59CB\u6267\u884CSQL ds.com.luoboduner.wesync.logic.runSqlFail=SQL\u6267\u884C\u5931\u8D25\uFF0C\u7531\u4E8E\u5176\u4E2D\u67D0\u4E9BSQL\u5F71\u54CD\u591A\u884C\uFF0C\u5DF2\u7ECF\u56DE\u6EDA\u4E8B\u52A1 ds.com.luoboduner.wesync.logic.runSqlFinish=SQL\u6267\u884C\u5B8C\u6210 ds.com.luoboduner.wesync.logic.syncFinish=\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSqlFail=->\u6267\u884CSQL\u5931\u8D25: ds.com.luoboduner.wesync.logic.runScheduleing=\u6309\u8BA1\u5212\u6267\u884C\u4E2D\u2026\u2026 ds.com.luoboduner.wesync.logic.manuSyncFinish=\u624B\u52A8\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentManuSyncFinish=\u672C\u6B21\u624B\u52A8\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSyncFinish=\u672C\u6B21\u540C\u6B65\u5B8C\u6210\uFF01 ds.com.luoboduner.wesync.logic.currentSnapDirBackFail=\u5907\u4EFD\u5F53\u524D\u5FEB\u7167\u6587\u4EF6\u5939\u5931\u8D25 ds.com.luoboduner.wesync.logic.ifLastSnapExistFail=\u5224\u65AD\u4E0A\u4E00\u6B21\u7684\u5FEB\u7167\u662F\u5426\u5B58\u5728\u5931\u8D25 ds.com.luoboduner.wesync.logic.newSnapFileFail=\u65B0\u5FEB\u7167\u6587\u4EF6\u5931\u8D25 ds.com.luoboduner.wesync.logic.beforeSnapMd5Fail=\u83B7\u53D6\u539F\u5FEB\u7167MD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.nowSnapMd5Fail=\u83B7\u53D6\u65B0\u5FEB\u7167MD5\u5931\u8D25 ds.com.luoboduner.wesync.logic.lineByLineDiffFail=\u9010\u884C\u5BF9\u6BD4\u5FEB\u7167csv\u5931\u8D25 ds.com.luoboduner.wesync.logic.restoreSnapBackFail=\u6062\u590D\u5FEB\u7167\u5907\u4EFD\u5931\u8D25\uFF1A ds.com.luoboduner.wesync.logic.tableChanged=:\u65B0\u5FEB\u7167\u4E0E\u539F\u5FEB\u7167\u8868\u5934\u4E0D\u4E00\u81F4\uFF0C\u8003\u8651\u8868\u7ED3\u6784\u662F\u5426\u5DF2\u7ECF\u53D8\u66F4\uFF1F ================================================ FILE: dist/snaps/role.csv ================================================ "Name" "3D设计师" "IT专员" "SEM" "SEO" "UI前端工程师" "部门经理" ================================================ FILE: dist/snaps/role_before.csv ================================================ "Name" "3D设计师" "IT专员" "UI前端工程师" "部门经理" ================================================ FILE: dist/snaps/user.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: dist/snaps/user_before.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: dist/snaps_bak/role.csv ================================================ "Name" "3D设计师" "IT专员" "SEM" "SEO" "UI前端工程师" "部门经理" ================================================ FILE: dist/snaps_bak/role_before.csv ================================================ "Name" "3D设计师" "IT专员" "UI前端工程师" "部门经理" ================================================ FILE: dist/snaps_bak/user.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: dist/snaps_bak/user_before.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: log_SQL/log_sql.csv ================================================ ================================================ FILE: memo.txt ================================================ JPanel(boolean isDoubleBuffered) 创建具有 FlowLayout 和指定缓冲策略的新 JPanel。 public JPanel(boolean isDoubleBuffered)创建具有 FlowLayout 和指定缓冲策略的新 JPanel。如果 isDoubleBuffered 为 true,则 JPanel 将使用双缓冲。 参数: isDoubleBuffered - 一个 boolean 值,为 true 表示双缓冲,使用更多内存空间实现快速、无闪烁的更新 ================================================ FILE: pom.xml ================================================ 4.0.0 com.zhoubochina.tool.wesync WeSync 1.0 jar UTF-8 UTF-8 1.8 1.2.1 3.1.3 3.9 6.0.6 8.4.1.jre8 2.1.3 5.1.11.RELEASE 1.1.6 1.0-FCS 2.5.1 ch.qos.logback logback-classic ${logback.version} com.vdurmont emoji-java ${emoji-java.version} com.opencsv opencsv ${opencsv.version} mysql mysql-connector-java ${mysql-connector-java.version} com.microsoft.sqlserver mssql-jdbc ${mssql-jdbc.version} org.dom4j dom4j ${dom4j.version} org.springframework.security spring-security-core ${spring-security-core.version} jaxen jaxen ${jaxen.version} saxpath saxpath ${saxpath.version} com.belerweb pinyin4j ${pinyin4j.version} org.apache.maven.plugins maven-compiler-plugin 3.6.1 1.8 1.8 UTF-8 org.apache.maven.plugins maven-jar-plugin 2.6 true lib/ com.luoboduner.wesync.App org.apache.maven.plugins maven-dependency-plugin 2.10 copy-dependencies package copy-dependencies ${project.build.directory}/lib ================================================ FILE: readme.md ================================================

WeSync-Logo

WeSync [![Build Status](https://travis-ci.org/rememberber/WeSync.svg?branch=master)](https://travis-ci.org/rememberber/WeSync) ============ com.luoboduner.wesync.ui ------- >Java Swing >some icons 功能特性 --------- >数据库同步,数据库间数据传输 >支持不同数据库间,不同表和不同表结构间数据同步 >支持同步过程中数据加工(可扩展) >支持失败事务回滚 >支持失败快照回滚 >目前支持SqlServer->MySQL >可扩展任意不同数据库间数据传输 速览 -----

WeSync

WeSync

WeSync

WeSync

WeSync

WeSync

环境依赖 --------- >Java 8 目录结构描述 ------------- >config:配置 >>config.xml:UI设置参数的持久化 >>Re-initialization.sql:还原相关表到初始化状态的memo >>zh-cn.properties:语言,国际化 >DB_Backup:备份相关 >>mysql_backup.bat:备份脚本 >>mysql_table_backup.sql:备份时执行的sql >log_SQL:记录每次执行的sql流水 >snaps:csv快照 >snaps_bak:csv快照备份 >TableField:表-字段 对应关系配置 >Trigger:同步出发机制配置 版本内容更新 ------------- 声明 ------- >图标来源:http://designmodo.com/linecons-free/ ================================================ FILE: snaps/role.csv ================================================ "Name" "3D设计师" "IT专员" "SEM" "SEO" "UI前端工程师" "部门经理" ================================================ FILE: snaps/role_before.csv ================================================ "Name" "3D设计师" "IT专员" "UI前端工程师" "部门经理" ================================================ FILE: snaps/user.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: snaps/user_before.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: snaps_bak/role.csv ================================================ "Name" "3D设计师" "IT专员" "SEM" "SEO" "UI前端工程师" "部门经理" ================================================ FILE: snaps_bak/role_before.csv ================================================ "Name" "3D设计师" "IT专员" "UI前端工程师" "部门经理" ================================================ FILE: snaps_bak/user.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: snaps_bak/user_before.csv ================================================ "id","Name","IDCardID","Telphone","Address","EMail","Status" "A1","张某","211918181765325431","15512345678","辽宁省葫芦岛",,"1" "D8","王某","211918181765325432","13912345678",,,"辽宁省葫芦岛" "32","李某","211918181765325433","15112345678","辽宁省葫芦岛",,"1" "7B","赵某","211918181765325434","13512345678",,,"1" "97","刘某","211918181765325435","15612345678","辽宁省葫芦岛",,"1" ================================================ FILE: src/main/java/com/luoboduner/wesync/App.java ================================================ package com.luoboduner.wesync; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.dialog.DbBackUpCreateDialog; import com.luoboduner.wesync.ui.panel.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; /** * 程序入口,主窗口Frame * * @author Bob */ public class App { private static final Logger logger = LoggerFactory.getLogger(App.class); private JFrame frame; public static JPanel mainPanelCenter; public static StatusPanel statusPanel; public static DatabasePanel databasePanel; public static SchedulePanel schedulePanel; public static BackupPanel backupPanel; public static SettingPanel settingPanel; /** * 新建备份dialog */ public static DbBackUpCreateDialog dbBackUpCreateDialog; /** * 程序入口main */ public static void main(String[] args) { EventQueue.invokeLater(() -> { try { App window = new App(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }); } /** * 构造,创建APP */ public App() { initialize(); StatusPanel.buttonStartSchedule.doClick(); } /** * 初始化frame内容 */ private void initialize() { logger.info("==================AppInitStart"); // 设置系统默认样式 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 初始化主窗口 frame = new JFrame(); frame.setBounds(UiConsts.MAIN_WINDOW_X, UiConsts.MAIN_WINDOW_Y, UiConsts.MAIN_WINDOW_WIDTH, UiConsts.MAIN_WINDOW_HEIGHT); frame.setTitle(UiConsts.APP_NAME); frame.setIconImage(UiConsts.IMAGE_ICON); frame.setBackground(UiConsts.MAIN_BACK_COLOR); JPanel mainPanel = new JPanel(true); mainPanel.setBackground(Color.white); mainPanel.setLayout(new BorderLayout()); ToolBarPanel toolbar = new ToolBarPanel(); statusPanel = new StatusPanel(); databasePanel = new DatabasePanel(); schedulePanel = new SchedulePanel(); backupPanel = new BackupPanel(); settingPanel = new SettingPanel(); mainPanel.add(toolbar, BorderLayout.WEST); mainPanelCenter = new JPanel(true); mainPanelCenter.setLayout(new BorderLayout()); mainPanelCenter.add(statusPanel, BorderLayout.CENTER); mainPanel.add(mainPanelCenter, BorderLayout.CENTER); // 添加数据库备份对话框 addDialog(); frame.add(mainPanel); frame.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowIconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeiconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeactivated(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowClosing(WindowEvent e) { if (!StatusPanel.buttonStartSchedule.isEnabled()) { JOptionPane.showMessageDialog(App.statusPanel, PropertyUtil.getProperty("ds.ui.mainwindow.exitconfirm"), "Sorry~", JOptionPane.WARNING_MESSAGE); } else { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } @Override public void windowClosed(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } }); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); logger.info("==================AppInitEnd"); } /** * 数据库备份对话框 */ private void addDialog() { // 数据库备份对话框 dbBackUpCreateDialog = new DbBackUpCreateDialog(frame, PropertyUtil.getProperty("ds.ui.mainwindow.dialog.newBackUp"), true); dbBackUpCreateDialog.init(); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/BackupManage.java ================================================ package com.luoboduner.wesync.logic; import com.luoboduner.wesync.tools.*; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; /** * 备份管理类 * * @author Bob */ public class BackupManage { /** * 创建生成mysql备份bat * * @param hostIP * @param userName * @param password * @param databaseName * @return */ public static boolean createMysqlBackBat(String hostIP, String userName, String password, String databaseName) { boolean isSuccess = true; // 写bat文件 File bat = new File(ConstantsLogic.BAT_DIR_MYSQL); BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(bat)); bw.write("@echo off & setlocal ENABLEEXTENSIONS"); bw.newLine(); bw.write("set BACKUP_PATH=" + ConstantsLogic.PATH_MYSQL_BAK); bw.newLine(); bw.write("set DATABASES=" + databaseName); bw.newLine(); bw.write("set HOST=" + hostIP); bw.newLine(); bw.write("set USERNAME=" + userName); bw.newLine(); bw.write("set PASSWORD=" + password); bw.newLine(); bw.write("set MYSQL=" + ConstantsTools.CONFIGER.getMysqlPath()); bw.newLine(); bw.write("set path_bin_mysql=%MYSQL%\\bin\\"); bw.newLine(); StringBuffer batContentPart2 = new StringBuffer(); batContentPart2.append("set YEAR=%date:~0,4%").append("\r\n"); batContentPart2.append("set MONTH=%date:~5,2%").append("\r\n"); batContentPart2.append("set DAY=%date:~8,2%").append("\r\n"); batContentPart2.append("set HOUR=%time:~0,2%").append("\r\n"); batContentPart2.append("set MINUTE=%time:~3,2%").append("\r\n"); batContentPart2.append("set SECOND=%time:~6,2%").append("\r\n"); batContentPart2.append("set DIR=%BACKUP_PATH%").append("\r\n"); batContentPart2.append("set ADDON=\"%YEAR%%MONTH%%DAY%_%HOUR%%MINUTE%%SECOND%\"").append("\r\n"); batContentPart2.append("if not exist %DIR% (").append("\r\n"); batContentPart2.append("mkdir %DIR%").append("\r\n"); batContentPart2.append(")").append("\r\n"); batContentPart2.append("if not exist %DIR% (").append("\r\n"); batContentPart2.append("echo Backup path: %DIR% not exists, create dir failed.").append("\r\n"); batContentPart2.append("goto exit").append("\r\n"); batContentPart2.append(")").append("\r\n"); batContentPart2.append("cd /d %DIR%").append("\r\n"); batContentPart2.append("echo Start dump databases...").append("\r\n"); batContentPart2.append("for %%D in (%DATABASES%) do (").append("\r\n"); batContentPart2.append("echo Dumping database %%D ...").append("\r\n"); batContentPart2 .append("%path_bin_mysql%mysqldump -h%HOST% -u%USERNAME% -p%PASSWORD% --skip-lock-tables %%D > %%D_%ADDON%.sql") .append("\r\n"); batContentPart2.append(")").append("\r\n"); batContentPart2.append("echo Done").append("\r\n"); batContentPart2.append(":exit"); bw.write(batContentPart2.toString()); bw.flush(); } catch (IOException e) { isSuccess = false; e.printStackTrace(); return false; } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return isSuccess; } /** * MySQL数据库导出 * * @param hostIP * @param userName * @param password * @param databaseName * @return */ public static boolean exportDatabase(String hostIP, String userName, String password, String databaseName) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.backuping"), LogLevel.INFO); boolean isSuccess = true; // 创建整库备份bat // isSuccess = createMysqlBackBat(hostIP, userName, password, // databaseName); // // Process ps = null; // try { // ps = Runtime.getRuntime().exec(ConstantsLogic.BAT_DIR_MYSQL); // // 取得命令结果的输出流 // InputStream fis = ps.getInputStream(); // // 用一个读输出流类去读 // InputStreamReader isr = new InputStreamReader(fis); // // 用缓冲器读行 // BufferedReader br = new BufferedReader(isr); // String line = null; // // 直到读完为止 // while ((line = br.readLine()) != null) { // StatusLog.setStatusDetail("正在备份MySQL数据库,请耐心等待:" + line, // LogLevel.INFO); // } // ps.waitFor(); // } catch (IOException | InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // 进行表备份 try { DbUtilMySQL mySql = DbUtilMySQL.getInstance(); ArrayList list = new ArrayList(); // 读取解析表备份sql文件 File file = new File(ConstantsLogic.MYSQL_TABLE_BACKUP_SQL_FILE); list = FileUtils.getSqlFileContentList(file); for (String string : list) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.backupTable") + string, LogLevel.INFO); mySql.executeUpdate(string); } mySql.getConnection().commit(); isSuccess = true; } catch (IOException | SQLException e1) { isSuccess = false; e1.printStackTrace(); StatusLog.setStatusDetail(e1.toString(), LogLevel.ERROR); } return isSuccess; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/ConstantsLogic.java ================================================ package com.luoboduner.wesync.logic; import java.io.File; import com.luoboduner.wesync.ui.UiConsts; /** * Logic层的常量类 * * @author Bob */ public class ConstantsLogic { // 各配置文件路径 /** * 表-字段配置文件 路径 */ public final static String TABLE_FIELD_DIR = UiConsts.CURRENT_DIR + File.separator + "TableField"; /** * 表-字段配置文件 路径 */ public final static String TABLE_FIELD_INIT_DIR = UiConsts.CURRENT_DIR + File.separator + "TableField" + File.separator + "init"; /** * Trigger配置文件 */ public final static String TRIGGER_FILE = UiConsts.CURRENT_DIR + File.separator + "Trigger" + File.separator + "Trigger.txt"; /** * 表快照文件 路径 */ public final static String SNAPS_DIR = UiConsts.CURRENT_DIR + File.separator + "snaps"; /** * 表快照文件备份 路径 */ public final static String SNAPS_BAK_DIR = UiConsts.CURRENT_DIR + File.separator + "snaps_bak"; /** * sql日志文件路径 */ public final static String LOG_SQL_DIR = UiConsts.CURRENT_DIR + File.separator + "log_SQL"; /** * sql日志文件 */ public final static String LOG_SQL = UiConsts.CURRENT_DIR + File.separator + "log_SQL" + File.separator + "log_sql.csv"; /** * mysql整库备份bat文件路径 */ public final static String BAT_DIR_MYSQL = UiConsts.CURRENT_DIR + File.separator + "DB_Backup" + File.separator + "mysql_backup.bat"; /** * mysql表备份sql文件路径 */ public final static String MYSQL_TABLE_BACKUP_SQL_FILE = UiConsts.CURRENT_DIR + File.separator + "DB_Backup" + File.separator + "mysql_table_backup.sql"; /** * mysql备份sql文件路径 */ public final static String PATH_MYSQL_BAK = UiConsts.CURRENT_DIR + File.separator + "DB_Backup" + File.separator + "Target"; // 正则表达式 /** * trigger配置文件,解析表名的正则 */ public final static String REGEX_TRIGGER_TABLE = "<([^<>]+)>"; /** * trigger配置文件,解析表主键的正则 */ public final static String REGEX_TRIGGER_PRIM_KEY = "\\(([^()]+)\\)"; /** * trigger配置文件,解析表字段的正则 */ public final static String REGEX_TRIGGER_FIELDS = "\\{([^{}]+)\\}"; /** * trigger配置文件,解析“其他条件或保留”的正则 */ public final static String REGEX_TRIGGER_OTHER = "\\[([^\\[\\]]+)\\]"; } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/ExecuteThread.java ================================================ package com.luoboduner.wesync.logic; import com.luoboduner.wesync.ui.panel.StatusPanel; import com.opencsv.CSVWriter; import com.luoboduner.wesync.logic.bean.Table; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.*; import java.io.*; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 执行器线程 * * @author Bob */ public class ExecuteThread extends Thread implements ExecuteThreadInterface { private static final Logger logger = LoggerFactory.getLogger(ExecuteThread.class); /** * 表-字段配置文件内容Map,key:目标表名,value:对应关系内容List */ public static LinkedHashMap> tableFieldMap; /** * TriggerMap,key:快照名,value:触发表 */ public static LinkedHashMap triggerMap; /** * 来源表Map,key:快照名,value:Table */ public static LinkedHashMap originalTablesMap; /** * 目标表Map,key:快照名,value:Table */ public static LinkedHashMap targetTablesMap; /** * 初始化变量 */ @Override public void init() { tableFieldMap = new LinkedHashMap<>(); triggerMap = new LinkedHashMap<>(); originalTablesMap = new LinkedHashMap<>(); targetTablesMap = new LinkedHashMap<>(); } /** * 测试连接 */ @Override public boolean testLink() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.testLinking"), LogLevel.INFO); StatusPanel.progressCurrent.setMaximum(2); StatusPanel.progressCurrent.setValue(0); boolean isLinkedPass = true; DbUtilSQLServer dbSQLServer = null; DbUtilMySQL dbMySQL = null; try { dbSQLServer = DbUtilSQLServer.getInstance(); Connection connSQLServer = dbSQLServer.testConnection(); StatusPanel.progressCurrent.setValue(1); dbMySQL = DbUtilMySQL.getInstance(); Connection connMySQL = dbMySQL.testConnection(); StatusPanel.progressCurrent.setValue(2); if (connSQLServer == null) { isLinkedPass = false; StatusLog.setStatusDetail("SQLServer " + PropertyUtil.getProperty("ds.logic.testLinkFail"), LogLevel.ERROR); } if (connMySQL == null) { isLinkedPass = false; StatusLog.setStatusDetail("connMySQL " + PropertyUtil.getProperty("ds.logic.testLinkFail"), LogLevel.ERROR); } StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.testLinkFinish"), LogLevel.INFO); } catch (Exception e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.testLinkFail") + e.toString(), LogLevel.ERROR); isLinkedPass = false; } finally { if (dbSQLServer != null) { try { dbSQLServer.close(); } catch (SQLException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.testLinkFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } if (dbMySQL != null) { try { dbMySQL.close(); } catch (SQLException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.testLinkFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } } return isLinkedPass; } /** * 解析配置文件 */ @Override public boolean analyseConfigFile() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startAnalyse"), LogLevel.INFO); boolean isAnalyseSuccess = true; // 解析表-字段对应关系文件 File tableFieldDir = null; // 如果快照文件夹不存在,则解析初始化表字段关系配置 File snapsDir = new File(ConstantsLogic.SNAPS_DIR); if (!snapsDir.exists()) { tableFieldDir = new File(ConstantsLogic.TABLE_FIELD_INIT_DIR); } else { tableFieldDir = new File(ConstantsLogic.TABLE_FIELD_DIR); } File[] tableFieldFiles = tableFieldDir.listFiles(); ArrayList list; StatusPanel.progressCurrent.setMaximum(tableFieldFiles.length); int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); for (File file : tableFieldFiles) { String fileName = file.getName(); if (!fileName.endsWith(".sql")) { progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } else { try { // 读取解析表-字段配置sql文件 list = FileUtils.getSqlFileContentList(file); String key = fileName.substring(0, fileName.lastIndexOf(".")); // 将表-字段配置文件内容存放到Map,key:表名,value:对应关系内容List tableFieldMap.put(key, list); } catch (IOException e) { isAnalyseSuccess = false; StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.AnalyseFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } } // 解析Trigger文件 File triggerFile = new File(ConstantsLogic.TRIGGER_FILE); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(triggerFile)); String lineTxt = null; while ((lineTxt = reader.readLine()) != null) { lineTxt = lineTxt.trim(); if ("".equals(lineTxt) || lineTxt.startsWith("//")) { // 跳过注释和空行 } else { if (lineTxt.contains("//")) { // 去掉注释 lineTxt = lineTxt.substring(0, lineTxt.indexOf("//")).trim(); } // 用]=<分隔比用=分隔准确,因为其他条件里也可能会有= String[] arr = lineTxt.split("\\]=\\<"); // 补上被split掉的"]" arr[0] = arr[0] + "]"; // 取来源表名和目标表名 String snapName = arr[0].substring(0, arr[0].indexOf(":")); String[] tarTableNames = new String[arr.length - 1]; // 获取来源表map<快照名,(表名,主键,字段,其他条件或保留)> Table tableOri = new Table(); // 匹配表名 Pattern p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_TABLE); Matcher matcher = p.matcher(arr[0]); while (matcher.find()) { tableOri.setTableName(matcher.group(1)); } // 匹配表主键 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_PRIM_KEY); matcher = p.matcher(arr[0]); while (matcher.find()) { tableOri.setPrimKey(matcher.group(1)); } // 匹配表字段 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_FIELDS); matcher = p.matcher(arr[0]); while (matcher.find()) { tableOri.setFields(matcher.group(1)); } // 匹配其他条件或保留 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_OTHER); matcher = p.matcher(arr[0]); while (matcher.find()) { tableOri.setOther(matcher.group(1)); } originalTablesMap.put(snapName, tableOri); for (int i = 1; i < arr.length; i++) { // 补上被split掉的"<" arr[i] = "<" + arr[i]; // 获取目标表map<快照名,(表名,主键,字段,其他条件或保留)> Table tableTar = new Table(); // 匹配表名 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_TABLE); matcher = p.matcher(arr[i]); while (matcher.find()) { String temp = matcher.group(1); tableTar.setTableName(temp); tarTableNames[i - 1] = temp; } // 匹配表主键 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_PRIM_KEY); matcher = p.matcher(arr[i]); while (matcher.find()) { tableTar.setPrimKey(matcher.group(1)); } // 匹配表字段 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_FIELDS); matcher = p.matcher(arr[i]); while (matcher.find()) { tableTar.setFields(matcher.group(1)); } // 匹配其他条件或保留 p = Pattern.compile(ConstantsLogic.REGEX_TRIGGER_OTHER); matcher = p.matcher(arr[i]); while (matcher.find()) { tableTar.setOther(matcher.group(1)); } targetTablesMap.put(snapName, tableTar); } triggerMap.put(snapName, tarTableNames); } } } catch (IOException e) { isAnalyseSuccess = false; StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.AnalyseTriggerFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { isAnalyseSuccess = false; StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.AnalyseTriggerFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } } if (isAnalyseSuccess) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.finishAnalyse"), LogLevel.INFO); } return isAnalyseSuccess; } /** * 备份 */ @Override public void backUp() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startBackUp"), LogLevel.INFO); StatusPanel.progressCurrent.setMaximum(100); String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(ConstantsTools.CONFIGER.getUserTo()); password = des.decrypt(ConstantsTools.CONFIGER.getPasswordTo()); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.to.err.decode") + e.toString()); e.printStackTrace(); } BackupManage.exportDatabase(ConstantsTools.CONFIGER.getHostTo(), user, password, ConstantsTools.CONFIGER.getNameTo()); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.finishBackUp"), LogLevel.INFO); } /** * 新建快照 */ @Override public boolean newSnap() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startNewSnap"), LogLevel.INFO); boolean isSuccess = true; isSuccess = SnapManage.createSnap(originalTablesMap); if (isSuccess) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.finishNewSnap"), LogLevel.INFO); } return isSuccess; } /** * 对比快照,并生成SQL */ @Override public boolean diffSnap() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startDiffSnap"), LogLevel.INFO); boolean isSuccess = true; isSuccess = SnapManage.diffSnap(originalTablesMap); if (isSuccess) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.finishDiffSnap"), LogLevel.INFO); } else { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.diffSnapFail"), LogLevel.ERROR); } return isSuccess; } /** * 执行SQL语句 * * @throws Exception */ @Override public boolean executeSQL() { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startRunSql"), LogLevel.INFO); boolean isSuccess = true; ArrayList sqlList = SnapManage.sqlList; // sql日志目录 File logSqlFileDir = new File(ConstantsLogic.LOG_SQL_DIR); if (!logSqlFileDir.exists()) { logSqlFileDir.mkdirs(); } // sql日志文件 File logSqlFile = new File(ConstantsLogic.LOG_SQL); CSVWriter csvWriter = null; // 总sql数 int totalSqls = 0; if (sqlList.size() != 0) { if ("false".equals(ConstantsTools.CONFIGER.getDebugMode())) { String sqlForLog = ""; try { if (!logSqlFile.exists()) { logSqlFile.createNewFile(); } // 整理触发器中生成的所有sql StringBuffer sqlBuff = new StringBuffer(); for (String string : sqlList) { String tempArr[] = string.split(";"); for (String tempSql : tempArr) { if (!"".equals(tempSql.trim())) { sqlBuff.append(tempSql).append(";"); } } } String[] sqls = sqlBuff.toString().split(";"); StatusPanel.progressCurrent.setMaximum(sqls.length); // 总sql数 totalSqls = 0; // 受影响的结果行数 int affectedRecords = 0; int progressValue = 0; for (String string : sqls) { if (!"".equals(string.trim())) { totalSqls++; sqlForLog = string; int result = DbUtilMySQL.getInstance().executeUpdate(string + ";"); affectedRecords += result; logger.warn("===" + string + ";===" + result); } progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } // 第二个参数:true表示在文件结尾追加 Writer writer = new FileWriter(logSqlFile, true); csvWriter = new CSVWriter(writer, ','); // log_sql第一列:系统时间,第二列:本次所有要执行的sql,第三列:执行结果受影响的总行数,第四列:是否成功 String[] logLine = new String[4]; // log_sql第一列,系统时间 logLine[0] = Utils.getCurrentTime(); // log_sql第二列,本次所有要执行的sql logLine[1] = sqlBuff.toString(); // log_sql第三列,执行结果受影响的总行数 logLine[2] = String.valueOf(affectedRecords); if ("true".equals(ConstantsTools.CONFIGER.getStrictMode())) { if (affectedRecords == totalSqls) { DbUtilMySQL.getInstance().getConnection().commit(); // log_sql第四列,执行结果成功 logLine[3] = "Success"; } else { DbUtilMySQL.getInstance().getConnection().rollback(); // log_sql第四列,执行结果失败 logLine[3] = "Fail"; StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.runSqlFail"), LogLevel.ERROR); return false; } } else { DbUtilMySQL.getInstance().getConnection().commit(); // log_sql第四列,执行结果成功 logLine[3] = "Success"; } if (!"".equals(logLine[1].trim())) { csvWriter.writeNext(logLine); csvWriter.flush(); } StatusLog.setLastTime(Utils.getCurrentTime()); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.runSqlFinish"), LogLevel.INFO); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.syncFinish"), LogLevel.INFO); return isSuccess; } catch (Exception e) { try { DbUtilMySQL.getInstance().getConnection().rollback(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } isSuccess = false; StatusLog.setStatusDetail("!!!" + sqlForLog + PropertyUtil.getProperty("ds.logic.currentSqlFail") + e.toString(), LogLevel.ERROR); } finally { if (csvWriter != null) { try { csvWriter.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } try { DbUtilMySQL.getInstance().close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } else { StatusPanel.progressCurrent.setMaximum(sqlList.size()); int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); for (String string : sqlList) { logger.debug("sqls:" + string); progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } } } else { StatusPanel.progressCurrent.setMaximum(1); StatusPanel.progressCurrent.setValue(1); StatusLog.setLastTime(Utils.getCurrentTime()); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.runSqlFinish") + totalSqls, LogLevel.INFO); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.syncFinish"), LogLevel.INFO); } return isSuccess; } @Override public void run() { StatusPanel.isRunning = true; this.setName("ExecuteThread"); long enterTime = System.currentTimeMillis(); StatusPanel.progressTotal.setMaximum(6); // 初始化变量 init(); // 测试连接 boolean isLinked = testLink(); if (isLinked) { StatusPanel.progressTotal.setValue(1); // 分析配置文件 boolean isAnalyseSuccess = analyseConfigFile(); if (isAnalyseSuccess) { StatusPanel.progressTotal.setValue(2); // 备份 if ("true".equals(ConstantsTools.CONFIGER.getAutoBak())) { backUp(); } StatusPanel.progressTotal.setValue(3); // 建立新快照 boolean isSnapSuccess = newSnap(); if (isSnapSuccess) { StatusPanel.progressTotal.setValue(4); // 对比快照,并根据对比结果生成SQL boolean isDiffSuccess = diffSnap(); if (isDiffSuccess) { StatusPanel.progressTotal.setValue(5); // 执行SQL boolean isExecuteSuccess = executeSQL(); if (isExecuteSuccess) { StatusPanel.progressTotal.setValue(6); // 恢复按钮状态 if (!StatusPanel.buttonStartSchedule.isEnabled()) { StatusLog.setStatus(PropertyUtil.getProperty("ds.logic.runScheduleing")); } else { StatusLog.setStatus(PropertyUtil.getProperty("ds.logic.manuSyncFinish")); } StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.currentManuSyncFinish"), LogLevel.INFO); // 设置持续时间 long leaveTime = System.currentTimeMillis(); float minutes = (float) (leaveTime - enterTime) / 1000; StatusLog.setKeepTime(String.valueOf(minutes)); // 设置成功次数+1 String success = String .valueOf((Long.parseLong(ConstantsTools.CONFIGER.getSuccessTime()) + 1)); StatusLog.setSuccess(success); } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } StatusPanel.buttonStartNow.setEnabled(true); StatusPanel.buttonStartSchedule.setEnabled(true); StatusPanel.isRunning = false; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/ExecuteThreadInterface.java ================================================ package com.luoboduner.wesync.logic; /** * 执行器的接口 * * @author Bob */ public interface ExecuteThreadInterface { /** * 初始化变量 */ void init(); /** * 测试连接 * * @return */ boolean testLink(); /** * 解析配置文件 * * @return */ boolean analyseConfigFile(); /** * 备份 */ void backUp(); /** * 建立快照 * * @return */ boolean newSnap(); /** * 对比快照,生成SQL * * @return */ boolean diffSnap(); /** * 执行SQL * * @return */ boolean executeSQL(); } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/ScheduleExecuteThread.java ================================================ package com.luoboduner.wesync.logic; import com.luoboduner.wesync.ui.panel.StatusPanel; import com.luoboduner.wesync.tools.*; /** * 定时任务执行器,继承于执行器线程类 * * @author Bob */ public class ScheduleExecuteThread extends ExecuteThread { @Override public void run() { if (!StatusPanel.isRunning) { StatusPanel.isRunning = true; this.setName("ScheduleExecuteThread"); StatusPanel.buttonStartNow.setEnabled(false); long enterTime = System.currentTimeMillis(); StatusPanel.progressTotal.setMaximum(6); // 初始化变量 init(); // 测试连接 boolean isLinked = testLink(); if (isLinked) { StatusPanel.progressTotal.setValue(1); // 分析配置文件 boolean isAnalyseSuccess = analyseConfigFile(); if (isAnalyseSuccess) { StatusPanel.progressTotal.setValue(2); // 备份 if ("true".equals(ConstantsTools.CONFIGER.getAutoBak())) { backUp(); } StatusPanel.progressTotal.setValue(3); // 建立新快照 boolean isSnapSuccess = newSnap(); if (isSnapSuccess) { StatusPanel.progressTotal.setValue(4); // 对比快照,并根据对比结果生成SQL boolean isDiffSuccess = diffSnap(); if (isDiffSuccess) { StatusPanel.progressTotal.setValue(5); // 执行SQL boolean isExecuteSuccess = executeSQL(); if (isExecuteSuccess) { StatusPanel.progressTotal.setValue(6); // 设置持续时间 long leaveTime = System.currentTimeMillis(); float minutes = (float) (leaveTime - enterTime) / 1000; StatusLog.setKeepTime(String.valueOf(minutes)); // 设置成功次数+1 String success = String .valueOf((Long.parseLong(ConstantsTools.CONFIGER.getSuccessTime()) + 1)); StatusLog.setSuccess(success); StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.currentSyncFinish"), LogLevel.INFO); } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String .valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { // 恢复快照备份 SnapManage.recoverSnapBak(); String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } } else { String fail = String.valueOf((Long.parseLong(ConstantsTools.CONFIGER.getFailTime()) + 1)); StatusLog.setFail(fail); } // 设置显示下一次执行时间 StatusPanel.labelNextTime.setText(PropertyUtil.getProperty("ds.ui.schedule.nextTime") + Utils.getNextSyncTime()); StatusPanel.isRunning = false; } } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/SnapManage.java ================================================ package com.luoboduner.wesync.logic; import com.luoboduner.wesync.ui.panel.StatusPanel; import com.opencsv.CSVWriter; import com.luoboduner.wesync.logic.bean.Table; import com.luoboduner.wesync.logic.init.Init4pxp2p; import com.luoboduner.wesync.tools.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.*; /** * 快照管理类 * * @author Bob */ public class SnapManage { public static ArrayList sqlList; /** * 创建快照 * * @param tableMap:来源表Map * @return */ public static boolean createSnap(Map tableMap) { boolean isSuccess = true; // 如果快照文件夹不存在,则进行初始化 File snapsDir = new File(ConstantsLogic.SNAPS_DIR); File snapsBakDir = new File(ConstantsLogic.SNAPS_BAK_DIR); if (!snapsDir.exists()) { boolean isInitSuccess = Init4pxp2p.init(); if (!isInitSuccess) { return false; } } if (!snapsBakDir.exists()) { snapsBakDir.mkdirs(); } // 备份当前快照文件夹,以便后续过程失败时恢复 try { // 清空快照备份文件夹 FileUtils.clearDirectiory(ConstantsLogic.SNAPS_BAK_DIR); // 拷贝到快照备份文件夹 FileUtils.copyDirectiory(ConstantsLogic.SNAPS_DIR, ConstantsLogic.SNAPS_BAK_DIR); } catch (IOException e1) { isSuccess = false; StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.currentSnapDirBackFail") + e1.toString(), LogLevel.ERROR); e1.printStackTrace(); return isSuccess; } StatusPanel.progressCurrent.setMaximum(tableMap.keySet().size()); int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); // 遍历来源表Map,建立快照 for (String snapName : tableMap.keySet()) { if (!"".equals(snapName.trim())) { // 上一次快照 File snapBefore = new File(ConstantsLogic.SNAPS_DIR + File.separator + snapName + "_before.csv"); // 当前快照 File snapNow = new File(ConstantsLogic.SNAPS_DIR + File.separator + snapName + ".csv"); // 判断上一次的快照是否存在,如果不存在,则新建一个空的 if (!snapBefore.exists()) { try { snapBefore.createNewFile(); } catch (IOException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.ifLastSnapExistFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } else { // 删除原快照,将当前快照变成原快照 snapBefore.delete(); snapNow.renameTo(new File(ConstantsLogic.SNAPS_DIR + File.separator + snapName + "_before.csv")); } // 建立当前快照,以便与原快照对比 // 新快照文件 CSVWriter csvWriter = null; DbUtilSQLServer sqlServer = null; try { snapNow.createNewFile(); Writer writer = new FileWriter(snapNow); csvWriter = new CSVWriter(writer, ','); // 获取SQLServer连接实例 sqlServer = DbUtilSQLServer.getInstance(); String querySql = "SELECT " + tableMap.get(snapName).getFields() + " FROM " + tableMap.get(snapName).getTableName(); if (tableMap.get(snapName).getOther() != null) { querySql += (" " + tableMap.get(snapName).getOther()); } // 表查询 ResultSet rs = sqlServer.executeQuery(querySql); // 获取列信息 ResultSetMetaData m; m = rs.getMetaData(); List list = new ArrayList(); int columns = m.getColumnCount(); // 表的表头 for (int i = 1; i <= columns; i++) { list.add(m.getColumnName(i)); } int size = list.size(); String[] arr = list.toArray(new String[size]); csvWriter.writeNext(arr); // 表的内容 while (rs.next()) { list.clear(); for (int i = 1; i <= columns; i++) { list.add(rs.getString(i)); } size = list.size(); String[] arr2 = list.toArray(new String[size]); csvWriter.writeNext(arr2); } } catch (IOException | SQLException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.newSnapFileFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } finally { if (csvWriter != null) { try { csvWriter.close(); } catch (IOException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.newSnapFileFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } if (sqlServer != null) { try { sqlServer.close(); } catch (SQLException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.newSnapFileFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } } } progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } return isSuccess; } /** * 对比快照 * * @param tableMap:来源表Map * @return */ public static boolean diffSnap(Map tableMap) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.startDiffSnap"), LogLevel.INFO); StatusPanel.progressCurrent.setMaximum(tableMap.keySet().size()); int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); boolean isSuccess = true; // 初始化目标sqlList sqlList = new ArrayList(); // 遍历来源表Map,对比快照 for (String snapName : tableMap.keySet()) { if (!"".equals(snapName.trim())) { // 上一次快照 File snapBefore = new File(ConstantsLogic.SNAPS_DIR + File.separator + snapName + "_before.csv"); // 当前快照 File snapNow = new File(ConstantsLogic.SNAPS_DIR + File.separator + snapName + ".csv"); // MD5比对两个文件 String snapMD5Before = FileUtils.getFileMD5(snapBefore); String snapMD5Now = FileUtils.getFileMD5(snapNow); if (snapMD5Before == null) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.beforeSnapMd5Fail") + snapBefore.getName(), LogLevel.ERROR); return false; } if (snapMD5Now == null) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.nowSnapMd5Fail") + snapNow.getName(), LogLevel.ERROR); return false; } if (snapMD5Before.equals(snapMD5Now)) { progressValue++; StatusPanel.progressCurrent.setValue(progressValue); continue; } else { try { isSuccess = diffCsvLineByLine(snapBefore, snapNow); } catch (Exception e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.lineByLineDiffFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); return false; } finally { if (TriggerManage.SQLServer != null) { try { TriggerManage.SQLServer.close(); } catch (SQLException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.lineByLineDiffFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } } } } progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.finishDiffSnap"), LogLevel.INFO); return isSuccess; } /** * 恢复快照备份 */ public static void recoverSnapBak() { // 清空快照文件夹 FileUtils.clearDirectiory(ConstantsLogic.SNAPS_DIR); // 拷贝快照备份到快照文件夹 try { FileUtils.copyDirectiory(ConstantsLogic.SNAPS_BAK_DIR, ConstantsLogic.SNAPS_DIR); } catch (IOException e) { StatusLog.setStatusDetail(PropertyUtil.getProperty("ds.logic.restoreSnapBackFail") + e.toString(), LogLevel.ERROR); e.printStackTrace(); } } /** * 逐行对比csv文件 * * @param snapBefore * @param snapNow * @throws IOException */ public static boolean diffCsvLineByLine(File snapBefore, File snapNow) throws Exception { boolean isSuccess = true; ArrayList snapBeforeList = FileUtils.getCsvFileContentList(snapBefore); ArrayList snapNowList = FileUtils.getCsvFileContentList(snapNow); // 去掉末尾空行,如果有的话 // if (snapBeforeList.get(snapBeforeList.size() - 1)[0] == null) { // snapBeforeList.remove(snapBeforeList.size() - 1); // } // // if (snapNowList.get(snapNowList.size() - 1)[0] == null) { // snapNowList.remove(snapNowList.size() - 1); // } // 获取该快照名 String snapName = snapNow.getName().substring(0, snapNow.getName().indexOf(".csv")); // 获取表头 String[] headerBefore; String[] headerNow = snapNowList.get(0); if (snapBeforeList.size() == 0) { // 如果原快照是空的,说明是第一次进行快照,所以将原快照加一个新快照表头即可 headerBefore = headerNow; } else { headerBefore = snapBeforeList.get(0); } // 对比表头,看表结构是否有变 // Arrays.sort(headerBefore); // Arrays.sort(headerNow); if (!Arrays.equals(headerBefore, headerNow)) { StatusLog.setStatusDetail(snapName + PropertyUtil.getProperty("ds.logic.tableChanged"), LogLevel.ERROR); return false; } // 获取主键 String primKeys = ExecuteThread.originalTablesMap.get(snapName).getPrimKey(); String[] primKeysArr = primKeys.split(","); // 获取主键index int[] prinKeyIndex = new int[primKeysArr.length]; for (int i = 0; i < primKeysArr.length; i++) { prinKeyIndex[i] = Utils.getStrArrIndex(headerNow, primKeysArr[i]); } // 主键比较+主键查找+游标控制法 // 获取原快照和新快照主键的值Set,多个主键值用逗号分隔 LinkedHashSet primKeyValuesSetBefore = new LinkedHashSet(); LinkedHashSet primKeyValuesSetNow = new LinkedHashSet(); for (int i = 0; i < snapBeforeList.size(); i++) { String[] recordsLineBefore = snapBeforeList.get(i); StringBuffer keyValues = new StringBuffer(); for (int j = 0; j < primKeysArr.length; j++) { keyValues.append(recordsLineBefore[prinKeyIndex[j]]); if (j < primKeysArr.length - 1) { keyValues.append(","); } } primKeyValuesSetBefore.add(keyValues.toString()); } for (int i = 0; i < snapNowList.size(); i++) { String[] recordsLineNow = snapNowList.get(i); StringBuffer keyValues = new StringBuffer(); for (int j = 0; j < primKeysArr.length; j++) { keyValues.append(recordsLineNow[prinKeyIndex[j]]); if (j < primKeysArr.length - 1) { keyValues.append(","); } } primKeyValuesSetNow.add(keyValues.toString()); } if (snapBeforeList.size() > snapNowList.size()) { StatusPanel.progressCurrent.setMaximum(snapBeforeList.size()); } else { StatusPanel.progressCurrent.setMaximum(snapNowList.size()); } int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); for (int flagBefore = 1, flagNow = 1; flagBefore < snapBeforeList.size() || flagNow < snapNowList.size(); ) { if (!(snapNowList.size() > flagNow)) { // 说明新快照到了结尾,后面没有内容了 String[] recordsLineBefore = snapBeforeList.get(flagBefore); // 生成原快照该条记录主键map,key:主键名,value:主键值 Map primKeyAndValueMapBefore = new LinkedHashMap<>(); for (int j = 0; j < primKeysArr.length; j++) { primKeyAndValueMapBefore.put(primKeysArr[j], recordsLineBefore[prinKeyIndex[j]]); } StringBuffer primKeyValuesBefore = new StringBuffer(); int k = 0; for (String key : primKeyAndValueMapBefore.keySet()) { primKeyValuesBefore.append(primKeyAndValueMapBefore.get(key)); if (k < primKeyAndValueMapBefore.keySet().size() - 1) { primKeyValuesBefore.append(","); } k++; } boolean isNowContainsBefore = primKeyValuesSetNow.contains(primKeyValuesBefore.toString()); if (!isNowContainsBefore) { // 生成主键map,key:主键名,value:主键值 Map primKeyAndValueMap = new HashMap<>(); for (k = 0; k < primKeysArr.length; k++) { primKeyAndValueMap.put(primKeysArr[k], recordsLineBefore[prinKeyIndex[k]]); } String sql = TriggerManage.getSqlDelete(snapName, primKeyAndValueMap, headerNow, recordsLineBefore); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } flagBefore++; } else if (!(snapBeforeList.size() > flagBefore)) { // 说明原快照到了结尾,后面没有内容了 String[] recordsLineNow = snapNowList.get(flagNow); // 生成新快照该条记录主键map,key:主键名,value:主键值 Map primKeyAndValueMapNow = new LinkedHashMap<>(); for (int j = 0; j < primKeysArr.length; j++) { primKeyAndValueMapNow.put(primKeysArr[j], recordsLineNow[prinKeyIndex[j]]); } // 看新记录主键的值在原快照主键值set中是否存在 StringBuffer primKeyValuesNow = new StringBuffer(); int k = 0; for (String key : primKeyAndValueMapNow.keySet()) { primKeyValuesNow.append(primKeyAndValueMapNow.get(key)); if (k < primKeyAndValueMapNow.keySet().size() - 1) { primKeyValuesNow.append(","); } k++; } boolean isBeforeContainsNow = primKeyValuesSetBefore.contains(primKeyValuesNow.toString()); if (!isBeforeContainsNow) { // 生成主键map,key:主键名,value:主键值 Map primKeyAndValueMap = new HashMap<>(); for (k = 0; k < primKeysArr.length; k++) { primKeyAndValueMap.put(primKeysArr[k], recordsLineNow[prinKeyIndex[k]]); } String sql = TriggerManage.getSqlInsert(snapName, primKeyAndValueMap, headerNow, recordsLineNow); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } flagNow++; } else { String[] recordsLineBefore = snapBeforeList.get(flagBefore); String[] recordsLineNow = snapNowList.get(flagNow); // 生成原快照该条记录主键map,key:主键名,value:主键值 Map primKeyAndValueMapBefore = new LinkedHashMap<>(); for (int j = 0; j < primKeysArr.length; j++) { primKeyAndValueMapBefore.put(primKeysArr[j], recordsLineBefore[prinKeyIndex[j]]); } // 生成新快照该条记录主键map,key:主键名,value:主键值 Map primKeyAndValueMapNow = new LinkedHashMap<>(); for (int j = 0; j < primKeysArr.length; j++) { primKeyAndValueMapNow.put(primKeysArr[j], recordsLineNow[prinKeyIndex[j]]); } if (Arrays.equals(recordsLineNow, recordsLineBefore)) { // 若完全一致,则继续下一行 flagBefore++; flagNow++; continue; } else { // 先看原快照该条记录和新快照该条记录主键是否一致 boolean isPrimKeyTheSame = Utils.mapCompare4PrimKey(primKeyAndValueMapBefore, primKeyAndValueMapNow); if (isPrimKeyTheSame) { // 若一致,说明该条记录内容有修改,需要触发Update // 通过Trigger生成UpdateSQL String sql = TriggerManage.getSqlUpdate(snapName, primKeyAndValueMapNow, headerNow, recordsLineBefore, recordsLineNow); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } else { // 若不一致,看原记录主键的值在新快照主键值set中是否存在 StringBuffer primKeyValuesBefore = new StringBuffer(); int k = 0; for (String key : primKeyAndValueMapBefore.keySet()) { primKeyValuesBefore.append(primKeyAndValueMapBefore.get(key)); if (k < primKeyAndValueMapBefore.keySet().size() - 1) { primKeyValuesBefore.append(","); } k++; } // 看新记录主键的值在原快照主键值set中是否存在 StringBuffer primKeyValuesNow = new StringBuffer(); k = 0; for (String key : primKeyAndValueMapNow.keySet()) { primKeyValuesNow.append(primKeyAndValueMapNow.get(key)); if (k < primKeyAndValueMapNow.keySet().size() - 1) { primKeyValuesNow.append(","); } k++; } boolean isNowContainsBefore = primKeyValuesSetNow.contains(primKeyValuesBefore.toString()); boolean isBeforeContainsNow = primKeyValuesSetBefore.contains(primKeyValuesNow.toString()); if (isNowContainsBefore && !isBeforeContainsNow) { // 说明新增了记录,则触发Insert // 通过Trigger生成InsertSQL String sql = TriggerManage.getSqlInsert(snapName, primKeyAndValueMapNow, headerNow, recordsLineNow); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); // 左边 String[] recordsLineNowTemp = snapNowList.get( Utils.getIndexInLinkedHashSet(primKeyValuesSetNow, primKeyValuesBefore.toString())); if (!Arrays.equals(recordsLineNowTemp, recordsLineBefore)) { // 若不完全一致,则Update sql = TriggerManage.getSqlUpdate(snapName, primKeyAndValueMapBefore, headerNow, recordsLineBefore, recordsLineNowTemp); sqlList.add(sql); snapNowList.set(Utils.getIndexInLinkedHashSet(primKeyValuesSetNow, primKeyValuesBefore.toString()), recordsLineBefore); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } } else if (!isNowContainsBefore && isBeforeContainsNow) { // 说明原记录被删除了,则触发Delete // 通过Trigger生成DeleteSQL String sql = TriggerManage.getSqlDelete(snapName, primKeyAndValueMapBefore, headerNow, recordsLineBefore); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); // 右边 String[] recordsLineBeforeTemp = snapBeforeList.get( Utils.getIndexInLinkedHashSet(primKeyValuesSetBefore, primKeyValuesNow.toString())); if (!Arrays.equals(recordsLineNow, recordsLineBeforeTemp)) { // 若不完全一致,则Update sql = TriggerManage.getSqlUpdate(snapName, primKeyAndValueMapNow, headerNow, recordsLineBeforeTemp, recordsLineNow); sqlList.add(sql); snapBeforeList.set(Utils.getIndexInLinkedHashSet(primKeyValuesSetBefore, primKeyValuesNow.toString()), recordsLineNow); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } } else if (isNowContainsBefore && isBeforeContainsNow) { // 说明该两条记录都有可能被更新了,还要继续拿出来比较一下 // 左边 String[] recordsLineNowTemp = snapNowList.get( Utils.getIndexInLinkedHashSet(primKeyValuesSetNow, primKeyValuesBefore.toString())); if (!Arrays.equals(recordsLineNowTemp, recordsLineBefore)) { // 若不完全一致,则Update String sql = TriggerManage.getSqlUpdate(snapName, primKeyAndValueMapBefore, headerNow, recordsLineBefore, recordsLineNowTemp); sqlList.add(sql); snapNowList.set(Utils.getIndexInLinkedHashSet(primKeyValuesSetNow, primKeyValuesBefore.toString()), recordsLineBefore); // snapBeforeList.remove(flagBefore); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } // 右边 String[] recordsLineBeforeTemp = snapBeforeList.get( Utils.getIndexInLinkedHashSet(primKeyValuesSetBefore, primKeyValuesNow.toString())); if (!Arrays.equals(recordsLineNow, recordsLineBeforeTemp)) { // 若不完全一致,则Update String sql = TriggerManage.getSqlUpdate(snapName, primKeyAndValueMapNow, headerNow, recordsLineBeforeTemp, recordsLineNow); sqlList.add(sql); snapBeforeList.set(Utils.getIndexInLinkedHashSet(primKeyValuesSetBefore, primKeyValuesNow.toString()), recordsLineNow); // snapNowList.remove(flagNow); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } } else if (!isNowContainsBefore && !isBeforeContainsNow) { // 既说明原记录被删除了,则触发Delete // 又说明新纪录被插入了,则触发Insert // 通过Trigger生成SQL String sql = TriggerManage.getSqlDelete(snapName, primKeyAndValueMapBefore, headerNow, recordsLineBefore); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); sql = TriggerManage.getSqlInsert(snapName, primKeyAndValueMapNow, headerNow, recordsLineNow); sqlList.add(sql); StatusLog.setStatusDetail(sql, LogLevel.DEBUG); } } flagBefore++; flagNow++; } } progressValue++; StatusPanel.progressCurrent.setValue(progressValue); } return isSuccess; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/TriggerManage.java ================================================ package com.luoboduner.wesync.logic; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.DbUtilMySQL; import com.luoboduner.wesync.tools.DbUtilSQLServer; import com.luoboduner.wesync.tools.Utils; import org.springframework.security.crypto.bcrypt.BCrypt; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author bob */ public class TriggerManage { public static DbUtilSQLServer SQLServer; public static DbUtilMySQL MySQL; private static final Pattern THIS_PATTERN = Pattern.compile("this\\.[.\\w]+"); private static final Pattern BEFORE_PATTERN = Pattern.compile("before\\.[.\\w]+"); private static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$([^$]+)\\$"); private static final Pattern BRACE_PATTERN = Pattern.compile("\\{([^{}]+)\\}"); private static final Pattern AT_SYMBOL_PATTERN = Pattern.compile("\\@([^@]+)\\@"); private static final Pattern BRACKET_PATTERN = Pattern.compile("\\(([^()]+)\\)"); private static final Pattern NUMBER_PATTERN = Pattern.compile("[0-9]*"); private static final Pattern HASH_MARK_PATTERN = Pattern.compile("\\#([^#]+)\\#"); public static String getSqlUpdate(String snapName, Map primKeyAndValueMap, String[] headerNow, String[] recordsLineBefore, String[] recordsLineNow) throws SQLException { StringBuffer sql = new StringBuffer(); // 当前record,Key:列名Value:列值 Map recordNowMap = new HashMap<>(); for (int i = 0; i < headerNow.length; i++) { recordNowMap.put(headerNow[i], recordsLineNow[i]); } // 原record,Key:列名Value:列值 Map recordBeforeMap = new HashMap<>(); for (int i = 0; i < headerNow.length; i++) { recordBeforeMap.put(headerNow[i], recordsLineBefore[i]); } // 触发的目标表 String[] targetTables = ExecuteThread.triggerMap.get(snapName); for (String targetTable : targetTables) { ArrayList list = ExecuteThread.tableFieldMap.get(targetTable + ".UPDATE"); for (String string : list) { sql.append(repairSqlString(string, recordBeforeMap, recordNowMap) + " "); } } return sql.toString(); } /** * @param primKeyAndValueMap * @param headerNow * @param recordsLineNow * @return * @throws SQLException */ public static String getSqlInsert(String snapName, Map primKeyAndValueMap, String[] headerNow, String[] recordsLineNow) throws SQLException { StringBuffer sql = new StringBuffer(); // 当前record,Key:列名Value:列值 Map recordNowMap = new HashMap<>(); for (int i = 0; i < headerNow.length; i++) { recordNowMap.put(headerNow[i], recordsLineNow[i]); } // 触发的目标表 String[] targetTables = ExecuteThread.triggerMap.get(snapName); for (String targetTable : targetTables) { ArrayList list = null; list = ExecuteThread.tableFieldMap.get(targetTable + ".INSERT"); for (String string : list) { sql.append(repairSqlString(string, null, recordNowMap) + " "); } } return sql.toString(); } public static String getSqlDelete(String snapName, Map primKeyAndValueMap, String[] headerNow, String[] recordsLineBefore) throws SQLException { StringBuffer sql = new StringBuffer(); // 原record,Key:列名Value:列值 Map recordBeforeMap = new HashMap<>(); for (int i = 0; i < headerNow.length; i++) { recordBeforeMap.put(headerNow[i], recordsLineBefore[i]); } // 触发的目标表 String[] targetTables = ExecuteThread.triggerMap.get(snapName); for (String targetTable : targetTables) { ArrayList list = ExecuteThread.tableFieldMap.get(targetTable + ".DELETE"); for (String string : list) { sql.append(repairSqlString(string, recordBeforeMap, null) + " "); } } return sql.toString(); } /** * 解析sql中的公式 * * @param string * @param recordNowMap * @return * @throws SQLException */ private static String repairSqlString(String string, Map recordBeforeMap, Map recordNowMap) throws SQLException { SQLServer = DbUtilSQLServer.getInstance(); if (string.contains("this.")) { // 第一级别公式:替换this.的内容 // this.***:取当前快照该条记录的某字段值 // before.***:取原快照该条记录的某字段值(仅UPDATE和DELETE时会用到) Matcher matcher = THIS_PATTERN.matcher(string); ArrayList strs = new ArrayList(); while (matcher.find()) { strs.add(matcher.group(0)); } for (String str : strs) { if (recordNowMap.containsKey(str.substring(str.indexOf(".") + 1))) { string = string.replaceAll(str, recordNowMap.get(str.substring(str.indexOf(".") + 1))); } } } if (string.contains("before.")) { // 第一级别公式:替换before.的内容 // this.***:取当前快照该条记录的某字段值 // before.***:取原快照该条记录的某字段值(仅UPDATE和DELETE时会用到) Matcher matcher = BEFORE_PATTERN.matcher(string); ArrayList strs = new ArrayList(); while (matcher.find()) { strs.add(matcher.group(0)); } for (String str : strs) { if (recordBeforeMap.containsKey(str.substring(str.indexOf(".") + 1))) { string = string.replaceAll(str, recordBeforeMap.get(str.substring(str.indexOf(".") + 1))); } } } if (string.contains("$")) { // 第二级别公式: // $INCREASE{POSITION_CODE}$:将大括号内的持久化变量递增(*在config文件中设置持久化变量) // $PINYIN{}$:将大括号内的汉字转为拼音 // $SYS_DATE_TIME$:系统日期+时间(2016-01-19 17:57:49) // $SQL{}$:执行大括号内的子查询sql,返回对应的查询结果(仅限一个) Matcher matcher = EXPRESSION_PATTERN.matcher(string); ArrayList strs = new ArrayList(); while (matcher.find()) { strs.add(matcher.group(0)); } for (String str : strs) { if (str.startsWith("$PINYIN")) { matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { string = string.replace(str, Utils.getPingYin(matcher.group(1).trim())); } } else if (str.startsWith("$SQL")) { matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { String tempSql = matcher.group(1); ResultSet rs = SQLServer.executeQuery(tempSql); String temp = ""; int rowCount = 0; while (rs.next()) { temp = rs.getString(1); rowCount++; } if (rowCount != 1 || temp == null) { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! temp = ""; } string = string.replace(str, temp); } } else if (str.startsWith("$SYS_DATE_TIME")) { string = string.replace(str, Utils.getCurrentTime()); } else if (str.startsWith("$INCREASE")) { matcher = BRACE_PATTERN.matcher(str); String para = ""; while (matcher.find()) { para = matcher.group(1); } if ("POSITION_CODE".equals(para)) { String positionCode = ConstantsTools.CONFIGER.getPositionCode();// 从config文件取出持久化的参数值 string = string.replace(str, String.format("%04d", Integer.parseInt(positionCode))); // 不足4位在前面补0 int pCode = Integer.parseInt(positionCode) + 1;// 加1之后进行持久化 try { ConstantsTools.CONFIGER.setPositionCode(String.valueOf(pCode)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { string = string.replace(str, ""); } } } } if (string.contains("@")) { // 第三级别公式: // @SUB(5,8){}@:将大括号内的字符串从第5个字符截取到第8个字符 // @SUB(5,END){}@:将大括号内的字符串从第5个字符截取到最后 // @SUB(0,LAST"."){}@:将大括号内的字符串从第0个字符截取到最后一个"." // @SUB("a",LAST"a"){}@:将大括号内的字符串从第1个"a"截取到最后一个"a"(不含左,不含右) Matcher matcher = AT_SYMBOL_PATTERN.matcher(string); ArrayList strs = new ArrayList(); while (matcher.find()) { strs.add(matcher.group(0)); } for (String str : strs) { if (str.startsWith("@SUB")) { // 先获取要截取的index和字符串内容 String[] indexs = null; String strContent = ""; matcher = BRACKET_PATTERN.matcher(str); while (matcher.find()) { indexs = matcher.group(1).split(","); } matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { strContent = matcher.group(1); } int beginIndex = 0; int endIndex = 0; if (NUMBER_PATTERN.matcher(indexs[0]).matches()) { beginIndex = Integer.parseInt(indexs[0]); } else { beginIndex = strContent.indexOf(indexs[0].replaceAll("\"", "")) + 1; } if (NUMBER_PATTERN.matcher(indexs[1]).matches()) { endIndex = Integer.parseInt(indexs[1]); } else if ("END".equals(indexs[1])) { endIndex = strContent.length(); } else if (indexs[1].startsWith("LAST")) { // if (strContent.contains(indexs[1].substring(5, // indexs[1].length() - 1))) { endIndex = strContent.lastIndexOf(indexs[1].substring(5, indexs[1].length() - 1)); // } else { // endIndex = strContent.length(); // } } string = string.replace(str, strContent.substring(beginIndex, endIndex)); } } } if (string.contains("#")) { // 第四级别公式: // #REPLACE("a","b"){}#将大括号内容中所有的"a"替换为"b" // #CASE(a=b,c=d,e=f){}#:如果大括号里边的内容是a,则替换为b;如果为c,则替换为d... Matcher matcher = HASH_MARK_PATTERN.matcher(string); ArrayList strs = new ArrayList(); while (matcher.find()) { strs.add(matcher.group(0)); } for (String str : strs) { if (str.startsWith("#REPLACE")) { // 先获取要替换的新旧字符串和内容 String[] indexs = null; String strContent = ""; matcher = BRACKET_PATTERN.matcher(str); while (matcher.find()) { indexs = matcher.group(1).split(","); } matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { strContent = matcher.group(1); } String oldStr = ""; String newStr = ""; oldStr = indexs[0].replaceAll("\"", ""); newStr = indexs[1].replaceAll("\"", ""); String temp = strContent.replace(oldStr, newStr); string = string.replace(str, temp); } else if (str.startsWith("#CASE")) { String[] keyValue = null; String strContent = ""; matcher = BRACKET_PATTERN.matcher(str); while (matcher.find()) { keyValue = matcher.group(1).split(","); } matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { strContent = matcher.group(1); } HashMap map = new HashMap(); for (String kV : keyValue) { String[] temp = kV.split("="); map.put(temp[0], temp[1]); } if (map.containsKey(strContent)) { string = string.replace(str, map.get(strContent)); } else { string = string.replace(str, ""); } } else if (str.startsWith("#MD5PE")) { String strContent = ""; matcher = BRACE_PATTERN.matcher(str); while (matcher.find()) { strContent = matcher.group(1); } BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); string = string.replace(str, bCryptPasswordEncoder.encode(strContent)); } } } return string; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/bean/Table.java ================================================ package com.luoboduner.wesync.logic.bean; /** * 表object类 * * @author Bob */ public class Table { /** * 表名 */ private String tableName; /** * 主键 */ private String primKey; /** * 字段 */ private String fields; /** * 其他条件/保留 */ private String other; public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public String getPrimKey() { return primKey; } public void setPrimKey(String primKey) { this.primKey = primKey; } public String getFields() { return fields; } public void setFields(String fields) { this.fields = fields; } public String getOther() { return other; } public void setOther(String other) { this.other = other; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/logic/init/Init4pxp2p.java ================================================ package com.luoboduner.wesync.logic.init; import com.luoboduner.wesync.ui.panel.StatusPanel; import com.opencsv.CSVWriter; import com.luoboduner.wesync.tools.DbUtilMySQL; import com.luoboduner.wesync.tools.DbUtilSQLServer; import com.luoboduner.wesync.tools.LogLevel; import com.luoboduner.wesync.tools.StatusLog; import java.io.File; public class Init4pxp2p { public static boolean init() { StatusLog.setStatusDetail("开始初始化第一次快照,请耐心等待……", LogLevel.INFO); boolean isSuccess = true; DbUtilMySQL mySql = DbUtilMySQL.getInstance(); DbUtilSQLServer sqlserver = DbUtilSQLServer.getInstance(); CSVWriter csvWriterRole = null; CSVWriter csvWriterUser = null; File snapsDir = null; StatusPanel.progressCurrent.setMaximum(7); int progressValue = 0; StatusPanel.progressCurrent.setValue(progressValue); /*Do Sth you need to init*/ return isSuccess; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/ConfigManager.java ================================================ package com.luoboduner.wesync.tools; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 配置文件管理 单例 * * @author Bob */ public class ConfigManager { private volatile static ConfigManager confManager; private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class); public Document document; /** * 私有的构造 */ private ConfigManager() { reloadDom(); } /** * 读取xml,加载到dom */ public void reloadDom() { SAXReader reader = new SAXReader(); try { document = reader.read(new File(ConstantsTools.PATH_CONFIG)); } catch (DocumentException e) { e.printStackTrace(); logger.error("Read config xml error:" + e.toString()); } } /** * 获取实例,线程安全 * * @return */ public static ConfigManager getConfigManager() { if (confManager == null) { synchronized (ConfigManager.class) { if (confManager == null) { confManager = new ConfigManager(); } } } return confManager; } /** * 把document对象写入新的文件 * * @throws Exception */ public void writeToXml() throws Exception { // 排版缩进的格式 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置编码 format.setEncoding("UTF-8"); // 创建XMLWriter对象,指定了写出文件及编码格式 XMLWriter writer = null; writer = new XMLWriter( new OutputStreamWriter(new FileOutputStream(new File(ConstantsTools.PATH_CONFIG)), StandardCharsets.UTF_8), format); // 写入 writer.write(document); writer.flush(); writer.close(); } public String getLastSyncTime() { return this.document.selectSingleNode(ConstantsTools.XPATH_LAST_SYNC_TIME).getText(); } public void setLastSyncTime(String lastSyncTime) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_LAST_SYNC_TIME).setText(lastSyncTime); writeToXml(); } public String getLastKeepTime() { return this.document.selectSingleNode(ConstantsTools.XPATH_LAST_KEEP_TIME).getText(); } public void setLastKeepTime(String lastKeepTime) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_LAST_KEEP_TIME).setText(lastKeepTime); writeToXml(); } public String getSuccessTime() { return this.document.selectSingleNode(ConstantsTools.XPATH_SUCCESS_TIME).getText(); } public void setSuccessTime(String successTime) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_SUCCESS_TIME).setText(successTime); writeToXml(); } public String getFailTime() { return this.document.selectSingleNode(ConstantsTools.XPATH_FAIL_TIME).getText(); } public void setFailTime(String failTime) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_FAIL_TIME).setText(failTime); writeToXml(); } public String getTypeFrom() { return this.document.selectSingleNode(ConstantsTools.XPATH_TYPE_FROM).getText(); } public void setTypeFrom(String typeFrom) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_TYPE_FROM).setText(typeFrom); writeToXml(); } public String getHostFrom() { return this.document.selectSingleNode(ConstantsTools.XPATH_HOST_FROM).getText(); } public void setHostFrom(String hostFrom) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_HOST_FROM).setText(hostFrom); writeToXml(); } public String getNameFrom() { return this.document.selectSingleNode(ConstantsTools.XPATH_NAME_FROM).getText(); } public void setNameFrom(String nameFrom) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_NAME_FROM).setText(nameFrom); writeToXml(); } public String getUserFrom() { return this.document.selectSingleNode(ConstantsTools.XPATH_USER_FROM).getText(); } public void setUserFrom(String userFrom) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_USER_FROM).setText(userFrom); writeToXml(); } public String getPasswordFrom() { return this.document.selectSingleNode(ConstantsTools.XPATH_PASSWORD_FROM).getText(); } public void setPasswordFrom(String passwordFrom) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_PASSWORD_FROM).setText(passwordFrom); writeToXml(); } public String getTypeTo() { return this.document.selectSingleNode(ConstantsTools.XPATH_TYPE_TO).getText(); } public void setTypeTo(String typeTo) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_TYPE_TO).setText(typeTo); writeToXml(); } public String getHostTo() { return this.document.selectSingleNode(ConstantsTools.XPATH_HOST_TO).getText(); } public void setHostTo(String hostTo) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_HOST_TO).setText(hostTo); writeToXml(); } public String getNameTo() { return this.document.selectSingleNode(ConstantsTools.XPATH_NAME_TO).getText(); } public void setNameTo(String nameTo) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_NAME_TO).setText(nameTo); writeToXml(); } public String getUserTo() { return this.document.selectSingleNode(ConstantsTools.XPATH_USER_TO).getText(); } public void setUserTo(String userTo) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_USER_TO).setText(userTo); writeToXml(); } public String getPasswordTo() { return this.document.selectSingleNode(ConstantsTools.XPATH_PASSWORD_TO).getText(); } public void setPasswordTo(String passwordTo) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_PASSWORD_TO).setText(passwordTo); writeToXml(); } public String getSchedule() { return this.document.selectSingleNode(ConstantsTools.XPATH_SCHEDULE).getText(); } public void setSchedule(String schedule) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_SCHEDULE).setText(schedule); writeToXml(); } public String getScheduleFixTime() { return this.document.selectSingleNode(ConstantsTools.XPATH_SCHEDULE_FIX_TIME).getText(); } public void setScheduleFixTime(String fixTime) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_SCHEDULE_FIX_TIME).setText(fixTime); writeToXml(); } public String getAutoBak() { return this.document.selectSingleNode(ConstantsTools.XPATH_AUTO_BAK).getText(); } public void setAutoBak(String autoBak) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_AUTO_BAK).setText(autoBak); writeToXml(); } public String getDebugMode() { return this.document.selectSingleNode(ConstantsTools.XPATH_DEBUG_MODE).getText(); } public void setDebugMode(String debugMode) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_DEBUG_MODE).setText(debugMode); writeToXml(); } public String getStrictMode() { return this.document.selectSingleNode(ConstantsTools.XPATH_STRICT_MODE).getText(); } public void setStrictMode(String strictMode) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_STRICT_MODE).setText(strictMode); writeToXml(); } public String getMysqlPath() { return this.document.selectSingleNode(ConstantsTools.XPATH_MYSQL_PATH).getText(); } public void setMysqlPath(String mysqlPath) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_MYSQL_PATH).setText(mysqlPath); writeToXml(); } public String getProductName() { return this.document.selectSingleNode(ConstantsTools.XPATH_PRODUCT_NAME).getText(); } public void setProductName(String productName) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_PRODUCT_NAME).setText(productName); writeToXml(); } public String getPositionCode() { return this.document.selectSingleNode(ConstantsTools.XPATH_POSITION_CODE).getText(); } public void setPositionCode(String positionCode) throws Exception { this.document.selectSingleNode(ConstantsTools.XPATH_POSITION_CODE).setText(positionCode); writeToXml(); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/ConstantsTools.java ================================================ package com.luoboduner.wesync.tools; import com.luoboduner.wesync.ui.UiConsts; import java.io.File; /** * 工具层相关的常量 * * @author Bob */ public class ConstantsTools { // 配置文件 /** * 配置文件 路径 */ public final static String PATH_CONFIG = UiConsts.CURRENT_DIR + File.separator + "config" + File.separator + "config.xml"; /** * properties路径 */ public final static String PATH_PROPERTY = UiConsts.CURRENT_DIR + File.separator + "config" + File.separator + "zh-cn.properties"; /** * 配置文件dom实例 */ public final static ConfigManager CONFIGER = ConfigManager.getConfigManager(); /** * xpath */ public final static String XPATH_LAST_SYNC_TIME = "//weSync/status/lastSyncTime"; public final static String XPATH_LAST_KEEP_TIME = "//weSync/status/lastKeepTime"; public final static String XPATH_SUCCESS_TIME = "//weSync/status/successTime"; public final static String XPATH_FAIL_TIME = "//weSync/status/failTime"; public final static String XPATH_TYPE_FROM = "//weSync/database/from/type"; public final static String XPATH_HOST_FROM = "//weSync/database/from/host"; public final static String XPATH_NAME_FROM = "//weSync/database/from/name"; public final static String XPATH_USER_FROM = "//weSync/database/from/user"; public final static String XPATH_PASSWORD_FROM = "//weSync/database/from/password"; public final static String XPATH_TYPE_TO = "//weSync/database/to/type"; public final static String XPATH_HOST_TO = "//weSync/database/to/host"; public final static String XPATH_NAME_TO = "//weSync/database/to/name"; public final static String XPATH_USER_TO = "//weSync/database/to/user"; public final static String XPATH_PASSWORD_TO = "//weSync/database/to/password"; public final static String XPATH_SCHEDULE = "//weSync/schedule/radio"; public final static String XPATH_SCHEDULE_FIX_TIME = "//weSync/schedule/fixtime"; public final static String XPATH_AUTO_BAK = "//weSync/setting/autoBak"; public final static String XPATH_DEBUG_MODE = "//weSync/setting/debugMode"; public final static String XPATH_STRICT_MODE = "//weSync/setting/strictMode"; public final static String XPATH_MYSQL_PATH = "//weSync/setting/mysqlPath"; public final static String XPATH_PRODUCT_NAME = "//weSync/setting/productname"; public final static String XPATH_POSITION_CODE = "//weSync/increase/POSITION_CODE"; /** * 日志文件 路径 */ public final static String PATH_LOG = UiConsts.CURRENT_DIR + File.separator + "log" + File.separator + "log.log"; } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/DESPlus.java ================================================ package com.luoboduner.wesync.tools; import com.sun.crypto.provider.SunJCE; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.MessageDigestPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.security.Key; import java.security.Security; public class DESPlus { private static String strDefaultKey = "HELP"; private Cipher encryptCipher; private Cipher decryptCipher; public static String byteArr2HexStr(byte[] arrB) { int iLen = arrB.length; StringBuffer sb = new StringBuffer(iLen * 2); for (int i = 0; i < iLen; i++) { int intTmp = arrB[i]; while (intTmp < 0) { intTmp += 256; } if (intTmp < 16) { sb.append("0"); } sb.append(Integer.toString(intTmp, 16)); } return sb.toString(); } public static byte[] hexStr2ByteArr(String strIn) { byte[] arrB = strIn.getBytes(); int iLen = arrB.length; byte[] arrOut = new byte[iLen / 2]; for (int i = 0; i < iLen; i += 2) { String strTmp = new String(arrB, i, 2); arrOut[(i / 2)] = (byte) Integer.parseInt(strTmp, 16); } return arrOut; } public DESPlus() throws Exception { this(strDefaultKey); } public DESPlus(String strKey) throws Exception { Security.addProvider(new SunJCE()); Key key = getKey(strKey.getBytes()); this.encryptCipher = Cipher.getInstance("DES"); this.encryptCipher.init(1, key); this.decryptCipher = Cipher.getInstance("DES"); this.decryptCipher.init(2, key); } public byte[] encrypt(byte[] arrB) throws Exception { return this.encryptCipher.doFinal(arrB); } public String encrypt(String strIn) throws Exception { return byteArr2HexStr(encrypt(strIn.getBytes())); } public byte[] decrypt(byte[] arrB) throws Exception { return this.decryptCipher.doFinal(arrB); } public String decrypt(String strIn) throws Exception { return new String(decrypt(hexStr2ByteArr(strIn))); } private Key getKey(byte[] arrBTmp) { byte[] arrB = new byte[8]; for (int i = 0; (i < arrBTmp.length) && (i < arrB.length); i++) { arrB[i] = arrBTmp[i]; } Key key = new SecretKeySpec(arrB, "DES"); return key; } public static void main(String[] args) { String test = "asdf"; String password = "asdfasdf"; try { DESPlus des = new DESPlus(); String miwen = des.encrypt(test); System.out.println("加密后的字符:" + miwen); DESPlus des1 = new DESPlus(); System.out.println("解密后的字符:" + des1.decrypt(miwen)); String passwordMiwen = des.encrypt(password); System.out.println("密码加密后的字符:" + passwordMiwen); DESPlus passwordDes1 = new DESPlus(); System.out.println("密码解密后的字符:" + passwordDes1.decrypt("asdfasdfasdf")); } catch (Exception e) { e.printStackTrace(); } BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); bCryptPasswordEncoder.encode("000000"); System.out.println(bCryptPasswordEncoder.encode("111111")); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/DbUtilMySQL.java ================================================ package com.luoboduner.wesync.tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.*; /** * MySQL数据库工具,单例,持久连接 * * @author Bob */ public class DbUtilMySQL { private Connection connection = null; private Statement statement = null; private ResultSet resultSet = null; private static String DBUrl = null; private static String DBName = null; private static String DBUser = null; private static String DBPassword = null; private static DbUtilMySQL instance = null; private static final Logger logger = LoggerFactory.getLogger(DbUtilMySQL.class); /** * 私有的构造 */ private DbUtilMySQL() { loadConfig(); } /** * 获取实例,线程安全 * * @return */ public static synchronized DbUtilMySQL getInstance() { if (instance == null) { instance = new DbUtilMySQL(); } return instance; } /** * 从配置文件加载设置数据库信息 */ private void loadConfig() { try { String dbclassname = "com.mysql.jdbc.Driver"; DBUrl = ConstantsTools.CONFIGER.getHostTo(); DBName = ConstantsTools.CONFIGER.getNameTo(); DBUser = ConstantsTools.CONFIGER.getUserTo(); DBPassword = ConstantsTools.CONFIGER.getPasswordTo(); Class.forName(dbclassname); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } /** * 获取连接,线程安全 * * @return * @throws SQLException */ public synchronized Connection getConnection() throws SQLException { String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(DBUser); password = des.decrypt(DBPassword); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.to.err.decode") + e.toString()); e.printStackTrace(); } // 当DB配置变更时重新获取 if (!ConstantsTools.CONFIGER.getHostTo().equals(DBUrl) || !ConstantsTools.CONFIGER.getNameTo().equals(DBName) || !ConstantsTools.CONFIGER.getUserTo().equals(DBUser) || !ConstantsTools.CONFIGER.getPasswordTo().equals(DBPassword)) { loadConfig(); // "jdbc:mysql://localhost/pxp2p_branch" connection = DriverManager.getConnection( "jdbc:mysql://" + DBUrl + "/" + DBName + "?useUnicode=true&characterEncoding=utf8", user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); } // 当connection失效时重新获取 if (connection == null || !connection.isValid(10)) { // "jdbc:mysql://localhost/pxp2p_branch" connection = DriverManager.getConnection( "jdbc:mysql://" + DBUrl + "/" + DBName + "?useUnicode=true&characterEncoding=utf8", user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); } if (connection == null) { logger.error("Can not load MySQL jdbc and get connection."); } return connection; } /** * 测试连接,线程安全 参数从配置文件获取 * * @return * @throws SQLException */ public synchronized Connection testConnection() throws SQLException { loadConfig(); // "jdbc:mysql://localhost/pxp2p_branch" String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(DBUser); password = des.decrypt(DBPassword); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.to.err.decode") + e.toString()); e.printStackTrace(); } connection = DriverManager.getConnection("jdbc:mysql://" + DBUrl + "/" + DBName, user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); if (connection == null) { logger.error("Can not load MySQL jdbc and get connection."); } return connection; } /** * 测试连接,线程安全 参数从入参获取 * * @return * @throws SQLException */ public synchronized Connection testConnection(String dburl, String dbname, String dbuser, String dbpassword) throws SQLException { loadConfig(); // "jdbc:mysql://localhost/pxp2p_branch" connection = DriverManager.getConnection("jdbc:mysql://" + dburl + "/" + dbname, dbuser, dbpassword); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); if (connection == null) { logger.error("Can not load MySQL jdbc and get connection."); } return connection; } /** * 获取数据库声明,私有,线程安全 * * @throws SQLException */ private synchronized void getStatement() throws SQLException { getConnection(); // 仅当statement失效时才重新创建 if (statement == null || statement.isClosed()) { statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } } /** * 关闭(结果集、声明、连接),线程安全 * * @throws SQLException */ public synchronized void close() throws SQLException { if (resultSet != null) { resultSet.close(); resultSet = null; } if (statement != null) { statement.close(); statement = null; } if (connection != null) { connection.close(); connection = null; } } /** * 执行查询,线程安全 * * @param sql * @return * @throws SQLException */ public synchronized ResultSet executeQuery(String sql) throws SQLException { getStatement(); if (resultSet != null && !resultSet.isClosed()) { resultSet.close(); } resultSet = null; resultSet = statement.executeQuery(sql); return resultSet; } /** * 执行更新,线程安全 * * @param sql * @return * @throws SQLException */ public synchronized int executeUpdate(String sql) throws SQLException { int result = 0; getStatement(); result = statement.executeUpdate(sql); return result; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/DbUtilSQLServer.java ================================================ package com.luoboduner.wesync.tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.*; /** * SQLServer数据库工具,单例,持久连接 * * @author Bob */ public class DbUtilSQLServer { private Connection connection = null; private Statement statement = null; private ResultSet resultSet = null; private static String DBUrl = null; private static String DBName = null; private static String DBUser = null; private static String DBPassword = null; private static DbUtilSQLServer instance = null; private static final Logger logger = LoggerFactory.getLogger(DbUtilSQLServer.class); /** * 私有的构造 */ private DbUtilSQLServer() { loadConfig(); } /** * 获取实例,线程安全 * * @return */ public static synchronized DbUtilSQLServer getInstance() { if (instance == null) { instance = new DbUtilSQLServer(); } return instance; } /** * 从配置文件加载设置数据库信息 */ private void loadConfig() { try { String dbclassname = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; DBUrl = ConstantsTools.CONFIGER.getHostFrom(); DBName = ConstantsTools.CONFIGER.getNameFrom(); DBUser = ConstantsTools.CONFIGER.getUserFrom(); DBPassword = ConstantsTools.CONFIGER.getPasswordFrom(); Class.forName(dbclassname); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } /** * 获取连接,线程安全 * * @return * @throws SQLException */ public synchronized Connection getConnection() throws SQLException { String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(DBUser); password = des.decrypt(DBPassword); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.from.err.decode") + e.toString()); e.printStackTrace(); } // 当DB配置变更时重新获取 if (!ConstantsTools.CONFIGER.getHostFrom().equals(DBUrl) || !ConstantsTools.CONFIGER.getNameFrom().equals(DBName) || !ConstantsTools.CONFIGER.getUserFrom().equals(DBUser) || !ConstantsTools.CONFIGER.getPasswordFrom().equals(DBPassword)) { loadConfig(); // "jdbc:sqlserver://20.1.1.194:1433;DatabaseName=AIS20151221115438;" connection = DriverManager.getConnection("jdbc:sqlserver://" + DBUrl + ";DatabaseName=" + DBName, user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); } // 当connection失效时重新获取 if (connection == null || connection.isValid(10) == false) { // "jdbc:sqlserver://20.1.1.194:1433;DatabaseName=AIS20151221115438;" connection = DriverManager.getConnection("jdbc:sqlserver://" + DBUrl + ";DatabaseName=" + DBName, user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); } if (connection == null) { logger.error("Can not load SQL Server jdbc and get connection."); } return connection; } /** * 测试连接,线程安全 参数从配置文件获取 * * @return * @throws SQLException */ public synchronized Connection testConnection() throws SQLException { loadConfig(); // "jdbc:sqlserver://20.1.1.194:1433;DatabaseName=AIS20151221115438;" String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(DBUser); password = des.decrypt(DBPassword); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.from.err.decode") + e.toString()); e.printStackTrace(); } connection = DriverManager.getConnection("jdbc:sqlserver://" + DBUrl + ";DatabaseName=" + DBName, user, password); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); if (connection == null) { logger.error("Can not load SQL Server jdbc and get connection."); } return connection; } /** * 测试连接,线程安全 参数从入参传入 * * @return * @throws SQLException */ public synchronized Connection testConnection(String dburl, String dbname, String dbuser, String dbpassword) throws SQLException { loadConfig(); // "jdbc:sqlserver://20.1.1.194:1433;DatabaseName=AIS20151221115438;" connection = DriverManager.getConnection("jdbc:sqlserver://" + dburl + ";DatabaseName=" + dbname, dbuser, dbpassword); // 把事务提交方式改为手工提交 connection.setAutoCommit(false); if (connection == null) { logger.error("Can not load SQL Server jdbc and get connection."); } return connection; } /** * 获取数据库声明,私有,线程安全 * * @throws SQLException */ private synchronized void getStatement() throws SQLException { getConnection(); // 仅当statement失效时才重新创建 if (statement == null || statement.isClosed()) { statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } } /** * 关闭(结果集、声明、连接),线程安全 * * @throws SQLException */ public synchronized void close() throws SQLException { if (resultSet != null) { resultSet.close(); resultSet = null; } if (statement != null) { statement.close(); statement = null; } if (connection != null) { connection.close(); connection = null; } } /** * 执行查询,线程安全 * * @param sql * @return * @throws SQLException */ public synchronized ResultSet executeQuery(String sql) throws SQLException { getStatement(); if (resultSet != null && !resultSet.isClosed()) { resultSet.close(); } resultSet = null; resultSet = statement.executeQuery(sql); return resultSet; } /** * 执行更新,线程安全 * * @param sql * @return * @throws SQLException */ public synchronized int executeUpdate(String sql) throws SQLException { int result = 0; getStatement(); result = statement.executeUpdate(sql); return result; } /** * 执行任意,线程安全 * * @param sql * @return * @throws SQLException */ public synchronized boolean execute(String sql) throws SQLException { boolean result; getStatement(); result = statement.execute(sql); return result; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/FileUtils.java ================================================ package com.luoboduner.wesync.tools; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Objects; import com.opencsv.CSVReader; /** * 文件工具类 * * @author Bob */ public class FileUtils { /** * 复制文件 * * @param sourceFile * @param targetFile * @throws IOException */ public static void copyFile(File sourceFile, File targetFile) throws IOException { // 新建文件输入流并对它进行缓冲 FileInputStream input = new FileInputStream(sourceFile); BufferedInputStream inBuff = new BufferedInputStream(input); // 新建文件输出流并对它进行缓冲 FileOutputStream output = new FileOutputStream(targetFile); BufferedOutputStream outBuff = new BufferedOutputStream(output); // 缓冲数组 byte[] b = new byte[1024 * 5]; int len; while ((len = inBuff.read(b)) != -1) { outBuff.write(b, 0, len); } // 刷新此缓冲的输出流 outBuff.flush(); // 关闭流 inBuff.close(); outBuff.close(); output.close(); input.close(); } /** * 复制文件夹 * * @param sourceDir * @param targetDir * @throws IOException */ public static void copyDirectiory(String sourceDir, String targetDir) throws IOException { // 新建目标目录 (new File(targetDir)).mkdirs(); // 获取源文件夹当前下的文件或目录 File[] file = (new File(sourceDir)).listFiles(); for (int i = 0; i < file.length; i++) { if (file[i].isFile()) { // 源文件 File sourceFile = file[i]; // 目标文件 File targetFile = new File(new File(targetDir).getAbsolutePath() + File.separator + file[i].getName()); copyFile(sourceFile, targetFile); } if (file[i].isDirectory()) { // 准备复制的源文件夹 String dir1 = sourceDir + "/" + file[i].getName(); // 准备复制的目标文件夹 String dir2 = targetDir + "/" + file[i].getName(); copyDirectiory(dir1, dir2); } } } /** * 计算文件的 MD5 值 * * @param file * @return */ public static String getFileMD5(File file) { if (!file.isFile()) { return null; } MessageDigest digest = null; FileInputStream in = null; byte[] buffer = new byte[8192]; int len; try { digest = MessageDigest.getInstance("MD5"); in = new FileInputStream(file); while ((len = in.read(buffer)) != -1) { digest.update(buffer, 0, len); } BigInteger bigInt = new BigInteger(1, digest.digest()); return bigInt.toString(16); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (in != null) { in.close(); } } catch (Exception e) { e.printStackTrace(); } } } /** * 计算文件的SHA-1值 * * @param file * @return */ public static String getFileSha1(File file) { if (!file.isFile()) { return null; } MessageDigest digest = null; FileInputStream in = null; byte[] buffer = new byte[8192]; int len; try { digest = MessageDigest.getInstance("SHA-1"); in = new FileInputStream(file); while ((len = in.read(buffer)) != -1) { digest.update(buffer, 0, len); } BigInteger bigInt = new BigInteger(1, digest.digest()); return bigInt.toString(16); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (in != null) { in.close(); } } catch (Exception e) { e.printStackTrace(); } } } /*** * 清空文件夹 * * @param dir */ public static void clearDirectiory(String dir) { File dirFile = new File(dir); for (File file : Objects.requireNonNull(dirFile.listFiles())) { file.delete(); } } /** * 读取csv文件到List * * @param csvFile * @return 内容List(每行的字符串数组) * @throws IOException */ public static ArrayList getCsvFileContentList(File csvFile) throws IOException { FileReader fReader = null; CSVReader csvReader = null; ArrayList list; try { // 初始化reader fReader = new FileReader(csvFile); csvReader = new CSVReader(fReader); // 读取解析csv文件 list = (ArrayList) csvReader.readAll(); return list; } catch (IOException e) { throw e; } finally { if (fReader != null) { try { fReader.close(); } catch (IOException e) { e.printStackTrace(); } } if (csvReader != null) { try { csvReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 读取sql文件到List * * @param sqlFile * @return 内容List(每行的字符串) * @throws IOException */ public static ArrayList getSqlFileContentList(File sqlFile) throws IOException { ArrayList list = new ArrayList(); BufferedReader br = null; try { // 初始化reader br = new BufferedReader(new InputStreamReader(new FileInputStream(sqlFile), StandardCharsets.UTF_8)); String lineTxt = null; while ((lineTxt = br.readLine()) != null) { lineTxt = lineTxt.trim(); if ("".equals(lineTxt) || lineTxt.startsWith("//")) { // 跳过注释和空行 } else { if (lineTxt.contains("//")) { // 去掉注释 lineTxt = lineTxt.substring(0, lineTxt.indexOf("//")).trim(); } list.add(lineTxt); } } return list; } catch (IOException e) { throw e; } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 转换文件大小 * * @param fileS * @return */ public static String formetfilesize(long fileS) { DecimalFormat df = new DecimalFormat("#.00"); String fileSizeString = ""; if (fileS < 1024) { fileSizeString = df.format((double) fileS) + "B"; } else if (fileS < 1048576) { fileSizeString = df.format((double) fileS / 1024) + "K"; } else if (fileS < 1073741824) { fileSizeString = df.format((double) fileS / 1048576) + "M"; } else { fileSizeString = df.format((double) fileS / 1073741824) + "G"; } return fileSizeString; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/LogLevel.java ================================================ package com.luoboduner.wesync.tools; /** * 日志级别枚举 * * @author Bob */ public enum LogLevel { INFO, DEBUG, WARN, ERROR, FATAL } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/PropertyUtil.java ================================================ package com.luoboduner.wesync.tools; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * Created by zhouy on 2017/2/27. */ public class PropertyUtil { /** * 获取property * * @param key * @return */ public static String getProperty(String key) { Properties pps = new Properties(); try { InputStream in = new BufferedInputStream(new FileInputStream(ConstantsTools.PATH_PROPERTY)); pps.load(in); String value = pps.getProperty(key); return value; } catch (IOException e) { e.printStackTrace(); return null; } } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/StatusLog.java ================================================ package com.luoboduner.wesync.tools; import com.luoboduner.wesync.ui.panel.StatusPanel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 日志封装类,控制系统信息(界面和log文件)的记录 * * @author Bob */ public class StatusLog { private static final Logger logger = LoggerFactory.getLogger(StatusLog.class); /** * 设置状态面板状态信息 * * @param status */ public static void setStatus(String status) { StatusPanel.labelStatus.setText(status); } /** * 设置状态面板状态的详细信息+写入日志文件(Debug模式下) * * @param statusDetail * @param level */ public static void setStatusDetail(String statusDetail, Enum level) { StatusPanel.labelStatusDetail.setText(PropertyUtil.getProperty("ds.tool.detail") + statusDetail); if ("true".equals(ConstantsTools.CONFIGER.getDebugMode())) { if ("INFO".equals(level.toString())) { logger.info(statusDetail); } else if ("DEBUG".equals(level.toString())) { logger.debug(statusDetail); } } if ("WARN".equals(level.toString())) { logger.warn(statusDetail); } else if ("ERROR".equals(level.toString())) { logger.error(statusDetail); } else if ("FATAL".equals(level.toString())) { logger.error(statusDetail); } } /** * 设置状态面板中上一次同步时间,并写入conf * * @param lastTime */ public static void setLastTime(String lastTime) { StatusPanel.labelLastTime.setText(PropertyUtil.getProperty("ds.ui.status.lastSync") + lastTime); try { ConstantsTools.CONFIGER.setLastSyncTime(lastTime); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } /** * 设置状态面板中的持续时间,并写入conf * * @param keepTime */ public static void setKeepTime(String keepTime) { StatusPanel.labelKeepTime.setText(PropertyUtil.getProperty("ds.ui.status.keepTime") + keepTime + PropertyUtil.getProperty("ds.ui.status.second")); try { ConstantsTools.CONFIGER.setLastKeepTime(keepTime); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } /** * 设置状态面板中下一次同步时间 * * @param nextTime */ public static void setNextTime(String nextTime) { StatusPanel.labelNextTime.setText(PropertyUtil.getProperty("ds.ui.schedule.nextTime") + nextTime); } /** * 设置状态面板中的成功总次数,并写入conf * * @param success */ public static void setSuccess(String success) { StatusPanel.labelSuccess.setText(PropertyUtil.getProperty("ds.ui.status.successTimes") + success); try { ConstantsTools.CONFIGER.setSuccessTime(success); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } /** * 设置状态面板中的失败总次数,并写入conf * * @param fail */ public static void setFail(String fail) { StatusPanel.labelFail.setText(PropertyUtil.getProperty("ds.ui.status.failTimes") + fail); try { ConstantsTools.CONFIGER.setFailTime(fail); } catch (Exception e) { logger.error(e.toString()); e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/Utils.java ================================================ package com.luoboduner.wesync.tools; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType; import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; /** * 小工具类 * * @author Bob */ public class Utils { /** * 获取系统当前时间yyyy-MM-dd HH:mm:ss * * @return */ public static String getCurrentTime() { // 设置日期格式 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return df.format(new Date()); } /** * 获取备份文件名(系统当前时间yyyy-MM-dd HHmmss) * * @return */ public static String getCurrentTimeForBakName() { // 设置日期格式 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HHmmss"); return df.format(new Date()); } /** * 计算下一次同步时间 * * @return */ public static String getNextSyncTime() { // 1、获取当前时间,获取到的时间类型是long类型的,单位是毫秒 long currentTime = System.currentTimeMillis(); // 2、在这个基础上加上定时执行时间: String schedule = ConstantsTools.CONFIGER.getSchedule(); if ("true,false,false,false,false,false,false".equals(schedule)) { currentTime += 5 * 60 * 1000; } else if ("false,true,false,false,false,false,false".equals(schedule)) { currentTime += 15 * 60 * 1000; } else if ("false,false,true,false,false,false,false".equals(schedule)) { currentTime += 30 * 60 * 1000; } else if ("false,false,false,true,false,false,false".equals(schedule)) { currentTime += 60 * 60 * 1000; } else if ("false,false,false,false,true,false,false".equals(schedule)) { currentTime += 24 * 60 * 60 * 1000; } else if ("false,false,false,false,false,true,false".equals(schedule)) { currentTime += 7 * 24 * 60 * 60 * 1000; } else if ("false,false,false,false,false,false,true".equals(schedule)) { return "明天 " + ConstantsTools.CONFIGER.getScheduleFixTime(); } // 3、格式化时间,获取到的就是当前时间加上定时执行之后的时间 Date date = new Date(currentTime); // 4、建立时间格式化对象: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return dateFormat.format(date); } /** * 获取某字符串在字符串数组中的index * * @param arr * @param key * @return 返回某字符串在字符串数组中的index,若找不到返回-1 */ public static int getStrArrIndex(String[] arr, String key) { for (int i = 0; i < arr.length; i++) { if (key.equals(arr[i])) { return i; } } return -1; } /** * 比较两个key完全相同的map内容是否完全一致 * * @param map1 * @param map2 * @return */ public static boolean mapCompare4PrimKey(Map map1, Map map2) { boolean ifEquals = true; for (String key : map1.keySet()) { if (!map1.get(key).equals(map2.get(key))) { ifEquals = false; } } return ifEquals; } /** * 将汉字转换为全拼 * * @param src * @return */ public static String getPingYin(String src) { char[] t1; t1 = src.toCharArray(); String[] t2; HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat(); t3.setCaseType(HanyuPinyinCaseType.LOWERCASE); t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE); t3.setVCharType(HanyuPinyinVCharType.WITH_V); String t4 = ""; int t0 = t1.length; try { for (int i = 0; i < t0; i++) { // 判断是否为汉字字符 if (Character.toString(t1[i]).matches("[\\u4E00-\\u9FA5]+")) { t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3); t4 += t2[0]; } else { t4 += Character.toString(t1[i]); } } return t4; } catch (BadHanyuPinyinOutputFormatCombination e1) { e1.printStackTrace(); } return t4; } /** * 获取linkedHashSet中元素的索引位置 * * @param linkedHashSet * @param string * @return */ public static int getIndexInLinkedHashSet(LinkedHashSet linkedHashSet, String string) { int index = -1; Iterator linkedSetStringIt = linkedHashSet.iterator(); while (linkedSetStringIt.hasNext()) { index++; String temp = linkedSetStringIt.next(); if (temp.equals(string)) { return index; } } return -1; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/tools/package-info.java ================================================ /** * 本包为工具包,包含各工具类 * * @author zhouy */ /** * @author zhouy * */ package com.luoboduner.wesync.tools; ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/UiConsts.java ================================================ package com.luoboduner.wesync.ui; import com.luoboduner.wesync.App; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; /** * UI相关的常量 * * @author Bob */ public class UiConsts { /** * 软件名称,版本 */ public final static String APP_NAME = "WeSync"; public final static String APP_VERSION = "v_1.60_160511"; /** * 主窗口大小 */ public final static int MAIN_WINDOW_X = 240; public final static int MAIN_WINDOW_Y = 100; public final static int MAIN_WINDOW_WIDTH = 885; public final static int MAIN_WINDOW_HEIGHT = 636; /** * 系统当前路径 */ public final static String CURRENT_DIR = System.getProperty("user.dir"); /** * 主窗口图标 */ public final static Image IMAGE_ICON = Toolkit.getDefaultToolkit() .getImage(App.class.getResource("/icon/WeSync.png")); /** * 主窗口背景色 */ public final static Color MAIN_BACK_COLOR = Color.WHITE; /** * 工具栏背景色 */ public final static Color TOOL_BAR_BACK_COLOR = new Color(37, 174, 96); /** * 表格线条背景色 */ public final static Color TABLE_LINE_COLOR = new Color(229, 229, 229); // 字体 /** * 标题字体 */ public final static Font FONT_TITLE = new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 27); /** * 普通字体 */ public final static Font FONT_NORMAL = new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 13); /** * radio字体 */ public final static Font FONT_RADIO = new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 15); /** * 主图标 */ public final static ImageIcon ICON_DATA_SYNC = new ImageIcon( App.class.getResource("/icon/WeSync.png")); // 工具栏图标 /** * 状态 默认 */ public final static ImageIcon ICON_STATUS = new ImageIcon( App.class.getResource("/icon/status.png")); /** * 状态 激活 */ public final static ImageIcon ICON_STATUS_ENABLE = new ImageIcon( App.class.getResource("/icon/statusEnable.png")); /** * 数据库 默认 */ public final static ImageIcon ICON_DATABASE = new ImageIcon( App.class.getResource("/icon/database.png")); /** * 数据库 激活 */ public final static ImageIcon ICON_DATABASE_ENABLE = new ImageIcon( App.class.getResource("/icon/databaseEnable.png")); /** * 执行计划 默认 */ public final static ImageIcon ICON_SCHEDULE = new ImageIcon( App.class.getResource("/icon/schedule.png")); /** * 执行计划 激活 */ public final static ImageIcon ICON_SCHEDULE_ENABLE = new ImageIcon( App.class.getResource("/icon/scheduleEnable.png")); /** * 设置 默认 */ public final static ImageIcon ICON_SETTING = new ImageIcon( App.class.getResource("/icon/setting.png")); /** * 设置 激活 */ public final static ImageIcon ICON_SETTING_ENABLE = new ImageIcon( App.class.getResource("/icon/settingEnable.png")); /** * 备份 默认 */ public final static ImageIcon ICON_BACKUP = new ImageIcon( App.class.getResource("/icon/backup.png")); /** * 备份 激活 */ public final static ImageIcon ICON_BACKUP_ENABLE = new ImageIcon( App.class.getResource("/icon/backupEnable.png")); // 按钮 图标 /** * 按计划执行 默认 */ public final static ImageIcon ICON_START_SCHEDULE = new ImageIcon( App.class.getResource("/icon/startSchedule.png")); /** * 按计划执行 激活 */ public final static ImageIcon ICON_START_SCHEDULE_ENABLE = new ImageIcon( App.class.getResource("/icon/startScheduleEnable.png")); /** * 按计划执行 失效 */ public final static ImageIcon ICON_START_SCHEDULE_DISABLE = new ImageIcon( App.class.getResource("/icon/startScheduleDisable.png")); /** * 停止 默认 */ public final static ImageIcon ICON_STOP = new ImageIcon( App.class.getResource("/icon/stop.png")); /** * 停止 激活 */ public final static ImageIcon ICON_STOP_ENABLE = new ImageIcon( App.class.getResource("/icon/stopEnable.png")); /** * 停止 失效 */ public final static ImageIcon ICON_STOP_DISABLE = new ImageIcon( App.class.getResource("/icon/stopDisable.png")); /** * 立即同步 默认 */ public final static ImageIcon ICON_SYNC_NOW = new ImageIcon( App.class.getResource("/icon/syncNow.png")); /** * 立即同步 激活 */ public final static ImageIcon ICON_SYNC_NOW_ENABLE = new ImageIcon( App.class.getResource("/icon/syncNowEnable.png")); /** * 立即同步 失效 */ public final static ImageIcon ICON_SYNC_NOW_DISABLE = new ImageIcon( App.class.getResource("/icon/syncNowDisable.png")); /** * 测试连接 默认 */ public final static ImageIcon ICON_TEST_LINK = new ImageIcon( App.class.getResource("/icon/testLinkButton.png")); /** * 测试连接 激活 */ public final static ImageIcon ICON_TEST_LINK_ENABLE = new ImageIcon( App.class.getResource("/icon/testLinkButtonEnable.png")); /** * 测试连接 失效 */ public final static ImageIcon ICON_TEST_LINK_DISABLE = new ImageIcon( App.class.getResource("/icon/testLinkButtonDisable.png")); /** * 保存 默认 */ public final static ImageIcon ICON_SAVE = new ImageIcon( App.class.getResource("/icon/saveButton.png")); /** * 保存 激活 */ public final static ImageIcon ICON_SAVE_ENABLE = new ImageIcon( App.class.getResource("/icon/saveButtonEnable.png")); /** * 保存 失效 */ public final static ImageIcon ICON_SAVE_DISABLE = new ImageIcon( App.class.getResource("/icon/saveButtonDisable.png")); /** * 新建备份 默认 */ public final static ImageIcon ICON_NEW_BAK = new ImageIcon( App.class.getResource("/icon/newBak.png")); /** * 新建备份 激活 */ public final static ImageIcon ICON_NEW_BAK_ENABLE = new ImageIcon( App.class.getResource("/icon/newBakEnable.png")); /** * 新建备份 失效 */ public final static ImageIcon ICON_NEW_BAK_DISABLE = new ImageIcon( App.class.getResource("/icon/newBakDisable.png")); /** * 删除备份 默认 */ public final static ImageIcon ICON_DEL_BAK = new ImageIcon( App.class.getResource("/icon/deleteBak.png")); /** * 删除备份 激活 */ public final static ImageIcon ICON_DEL_BAK_ENABLE = new ImageIcon( App.class.getResource("/icon/deleteBakEnable.png")); /** * 删除备份 失效 */ public final static ImageIcon ICON_DEL_BAK_DISABLE = new ImageIcon( App.class.getResource("/icon/deleteBakDisable.png")); /** * 还原备份 默认 */ public final static ImageIcon ICON_RECOVER_BAK = new ImageIcon( App.class.getResource("/icon/recoverBak.png")); /** * 还原备份 激活 */ public final static ImageIcon ICON_RECOVER_BAK_ENABLE = new ImageIcon( App.class.getResource("/icon/recoverBakEnable.png")); /** * 还原备份 失效 */ public final static ImageIcon ICON_RECOVER_BAK_DISABLE = new ImageIcon( App.class.getResource("/icon/recoverBakDisable.png")); /** * 清空所有备份 默认 */ public final static ImageIcon ICON_CLEAR_ALL_BAKS = new ImageIcon( App.class.getResource("/icon/clearAllBaks.png")); /** * 清空所有备份 激活 */ public final static ImageIcon ICON_CLEAR_ALL_BAKS_ENABLE = new ImageIcon( App.class.getResource("/icon/clearAllBaksEnable.png")); /** * 清空所有备份 失效 */ public final static ImageIcon ICON_CLEAR_ALL_BAKS_DISABLE = new ImageIcon( App.class.getResource("/icon/clearAllBaksDisable.png")); /** * 表字段对应关系 默认 */ public final static ImageIcon ICON_TABLE_FIELD = new ImageIcon( App.class.getResource("/icon/tableFiled.png")); /** * 表字段对应关系 激活 */ public final static ImageIcon ICON_TABLE_FIELD_ENABLE = new ImageIcon( App.class.getResource("/icon/tableFiledEnable.png")); /** * 表字段对应关系 失效 */ public final static ImageIcon ICON_TABLE_FIELD_DISABLE = new ImageIcon( App.class.getResource("/icon/tableFiledDisable.png")); /** * 清空Log 默认 */ public final static ImageIcon ICON_CLEAR_LOG = new ImageIcon( App.class.getResource("/icon/clearLog.png")); /** * 清空Log 激活 */ public final static ImageIcon ICON_CLEAR_LOG_ENABLE = new ImageIcon( App.class.getResource("/icon/clearLogEnable.png")); /** * 清空Log 失效 */ public final static ImageIcon ICON_CLEAR_LOG_DISABLE = new ImageIcon( App.class.getResource("/icon/clearLogDisable.png")); // 样式布局相关 /** * 主面板水平间隔 */ public final static int MAIN_H_GAP = 25; /** * 主面板Label 大小 */ public final static Dimension LABLE_SIZE = new Dimension(1300, 30); /** * Item Label 大小 */ public final static Dimension LABLE_SIZE_ITEM = new Dimension(78, 30); /** * Item text field 大小 */ public final static Dimension TEXT_FIELD_SIZE_ITEM = new Dimension(400, 24); /** * radio 大小 */ public final static Dimension RADIO_SIZE = new Dimension(1300, 60); /** * 高级选项面板Item 大小 */ public final static Dimension PANEL_ITEM_SIZE = new Dimension(1300, 40); } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/component/MyIconButton.java ================================================ package com.luoboduner.wesync.ui.component; import java.awt.Insets; import javax.swing.ImageIcon; import javax.swing.JButton; /** * 自定义按钮类,支持自定义默认图标、激活图标、失效图标和tip提示 * * @author Bob */ public class MyIconButton extends JButton { private static final long serialVersionUID = 1L; private ImageIcon iconEnable, iconDisable; private String tip; /** * 构造 * * @param iconNormal 默认图标 * @param iconEnable 激活图标 * @param iconDisable 失效图标 * @param tip 提示 */ public MyIconButton(ImageIcon iconNormal, ImageIcon iconEnable, ImageIcon iconDisable, String tip) { super(iconNormal); this.iconEnable = iconEnable; this.iconDisable = iconDisable; this.tip = tip; initialize(); setUp(); } /** * 初始化,设置按钮属性:无边,无焦点渲染,无内容区,各边距0 */ private void initialize() { this.setBorderPainted(false); this.setFocusPainted(false); this.setContentAreaFilled(false); this.setFocusable(true); this.setMargin(new Insets(0, 0, 0, 0)); } /** * 设置按钮图标:鼠标移过、按压、失效的图标 和设置按钮提示 */ private void setUp() { this.setRolloverIcon(iconEnable); // this.setSelectedIcon(iconEnable); this.setPressedIcon(iconEnable); this.setDisabledIcon(iconDisable); if (!tip.equals("")) { this.setToolTipText(tip); } } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/dialog/DbBackUpCreateDialog.java ================================================ package com.luoboduner.wesync.ui.dialog; import com.luoboduner.wesync.tools.PropertyUtil; import com.luoboduner.wesync.ui.UiConsts; import javax.swing.*; import java.awt.*; /** *
 * 新建备份dialog
 * 
* * @author Zhou Bo * @since 2019/2/27. */ public class DbBackUpCreateDialog extends JDialog { public DbBackUpCreateDialog(JFrame frame, String property, boolean b) { super(frame, property, b); } public void init() { this.setBounds(460, 220, 400, 250); JPanel panelDialog = new JPanel(new BorderLayout()); panelDialog.setBackground(UiConsts.MAIN_BACK_COLOR); JPanel panelDialogCenter = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 10)); JPanel panelDialogDown = new JPanel(new GridLayout(1, 2)); JPanel grid1 = new JPanel(new FlowLayout(FlowLayout.RIGHT, 20, 20)); JPanel grid2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 20)); JLabel labelType = new JLabel(PropertyUtil.getProperty("ds.ui.mainwindow.dialog.type")); JLabel labelComment = new JLabel(PropertyUtil.getProperty("ds.ui.mainwindow.dialog.remarks")); JLabel labelProgress = new JLabel(PropertyUtil.getProperty("ds.ui.mainwindow.dialog.progress")); JComboBox comboxType = new JComboBox<>(new String[]{PropertyUtil.getProperty("ds.ui.mainwindow.dialog.comboxType0"), PropertyUtil.getProperty("ds.ui.mainwindow.dialog.comboxType1"), PropertyUtil.getProperty("ds.ui.mainwindow.dialog.comboxType2"), PropertyUtil.getProperty("ds.ui.mainwindow.dialog.comboxType3")}); JTextField textFieldComment = new JTextField(); JProgressBar progressbar = new JProgressBar(); labelType.setFont(UiConsts.FONT_NORMAL); labelComment.setFont(UiConsts.FONT_NORMAL); labelProgress.setFont(UiConsts.FONT_NORMAL); comboxType.setFont(UiConsts.FONT_NORMAL); textFieldComment.setFont(UiConsts.FONT_NORMAL); Dimension preferredSize = new Dimension(250, 30); comboxType.setPreferredSize(preferredSize); textFieldComment.setPreferredSize(preferredSize); progressbar.setPreferredSize(preferredSize); panelDialogCenter.add(labelType); panelDialogCenter.add(comboxType); panelDialogCenter.add(labelComment); panelDialogCenter.add(textFieldComment); panelDialogCenter.add(labelProgress); panelDialogCenter.add(progressbar); JButton buttonSure = new JButton(PropertyUtil.getProperty("ds.ui.sure")); JButton buttonCancel = new JButton(PropertyUtil.getProperty("ds.ui.cancel")); buttonSure.setFont(UiConsts.FONT_NORMAL); buttonCancel.setFont(UiConsts.FONT_NORMAL); grid1.add(buttonSure); grid2.add(buttonCancel); panelDialogDown.add(grid1); panelDialogDown.add(grid2); panelDialog.add(panelDialogCenter, BorderLayout.CENTER); panelDialog.add(panelDialogDown, BorderLayout.SOUTH); this.add(panelDialog); buttonCancel.addActionListener(e -> this.setVisible(false)); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/BackupPanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import com.luoboduner.wesync.logic.ConstantsLogic; import com.luoboduner.wesync.tools.FileUtils; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.io.File; /** * 备份面板 * * @author Bob */ public class BackupPanel extends JPanel { private static final long serialVersionUID = 1L; public static JTable tableFrom; private static MyIconButton buttonNewBakFrom; private static Object[][] tableDatas; /** * 构造 */ public BackupPanel() { initialize(); initTableData(); addComponent(); addListener(); } /** * 初始化面板 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 为面板添加组件 */ private void addComponent() { this.add(getUpPanel(), BorderLayout.NORTH); this.add(getCenterPanel(), BorderLayout.CENTER); } /** * 面板上部 * * @return */ private JPanel getUpPanel() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.MAIN_BACK_COLOR); panelUp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); JLabel labelTitle = new JLabel(PropertyUtil.getProperty("ds.ui.backup.title")); labelTitle.setFont(UiConsts.FONT_TITLE); labelTitle.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.add(labelTitle); return panelUp; } /** * 面板中部 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(1, 1)); panelCenter.add(getPanelGridBakFrom()); return panelCenter; } /** * 数据库来源Grid面板 * * @return */ private JPanel getPanelGridBakFrom() { // 来源备份Grid JPanel panelGridBakFrom = new JPanel(); panelGridBakFrom.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridBakFrom.setLayout(new BorderLayout()); JPanel panelFromControl = new JPanel(); panelFromControl.setLayout(new GridLayout(1, 2)); JPanel panelFromTable = new JPanel(); panelFromTable.setLayout(new BorderLayout()); // 初始化控制组件 JPanel panelFromControlLeft = new JPanel(); panelFromControlLeft.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); panelFromControlLeft.setBackground(UiConsts.MAIN_BACK_COLOR); JPanel panelFromControlRight = new JPanel(); panelFromControlRight.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 5)); panelFromControlRight.setBackground(UiConsts.MAIN_BACK_COLOR); JLabel labelFrom = new JLabel(PropertyUtil.getProperty("ds.ui.database.label.to")); labelFrom.setFont(new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 18)); labelFrom.setForeground(Color.gray); panelFromControlLeft.add(labelFrom); buttonNewBakFrom = new MyIconButton(UiConsts.ICON_NEW_BAK, UiConsts.ICON_NEW_BAK_ENABLE, UiConsts.ICON_NEW_BAK_DISABLE, ""); MyIconButton buttonRecvBakFrom = new MyIconButton(UiConsts.ICON_RECOVER_BAK, UiConsts.ICON_RECOVER_BAK_ENABLE, UiConsts.ICON_RECOVER_BAK_DISABLE, ""); MyIconButton buttonDelBakFrom = new MyIconButton(UiConsts.ICON_DEL_BAK, UiConsts.ICON_DEL_BAK_ENABLE, UiConsts.ICON_DEL_BAK_DISABLE, ""); panelFromControlRight.add(buttonNewBakFrom); panelFromControlRight.add(buttonRecvBakFrom); panelFromControlRight.add(buttonDelBakFrom); panelFromControl.add(panelFromControlLeft); panelFromControl.add(panelFromControlRight); panelGridBakFrom.add(panelFromControl, BorderLayout.NORTH); // 初始化表格组件 tableFrom = new JTable(tableDatas, new String[]{PropertyUtil.getProperty("ds.ui.backup.table.head0"), PropertyUtil.getProperty("ds.ui.backup.table.head1"), PropertyUtil.getProperty("ds.ui.backup.table.head2")}); tableFrom.setFont(UiConsts.FONT_NORMAL); tableFrom.getTableHeader().setFont(UiConsts.FONT_NORMAL); tableFrom.getTableHeader().setBackground(UiConsts.TOOL_BAR_BACK_COLOR); tableFrom.setRowHeight(31); tableFrom.setGridColor(UiConsts.TABLE_LINE_COLOR); tableFrom.setSelectionBackground(UiConsts.TOOL_BAR_BACK_COLOR); // 设置列宽 tableFrom.getColumnModel().getColumn(0).setPreferredWidth(50); tableFrom.getColumnModel().getColumn(0).setMaxWidth(50); tableFrom.getColumnModel().getColumn(2).setPreferredWidth(150); tableFrom.getColumnModel().getColumn(2).setMaxWidth(150); JScrollPane panelScroll = new JScrollPane(tableFrom); panelScroll.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridBakFrom.add(panelScroll, BorderLayout.CENTER); return panelGridBakFrom; } public static void initTableData() { File bakupFilesDir = new File(ConstantsLogic.PATH_MYSQL_BAK); if (!bakupFilesDir.exists()) { bakupFilesDir.mkdirs(); } File[] bakupFiles = bakupFilesDir.listFiles(); tableDatas = new Object[bakupFiles.length][3]; for (int i = 0; i < bakupFiles.length; i++) { tableDatas[i] = new Object[]{i + 1, bakupFiles[i].getName(), FileUtils.formetfilesize(bakupFiles[i].length())}; } } private void addListener() { buttonNewBakFrom.addActionListener(e -> App.dbBackUpCreateDialog.setVisible(true)); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/DatabasePanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; /** * 数据库设置面板 * * @author Bob */ public class DatabasePanel extends JPanel { private static final long serialVersionUID = 1L; public static JPanel panelFrom; public static JPanel panelTo; public static JPanel databaseSettingPanel; private static JPanel databaseSettingPanelFrom; private static JPanel databaseSettingPanelTo; /** * 构造 */ public DatabasePanel() { initialize(); addComponent(); addListener(); } /** * 初始化面板 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); databaseSettingPanelFrom = new DatabasePanelFrom(); databaseSettingPanelTo = new DatabasePanelTo(); } /** * 为面板添加组件 */ private void addComponent() { this.add(getUpPanel(), BorderLayout.NORTH); this.add(getCenterPanel(), BorderLayout.CENTER); } /** * 面板上部 * * @return */ private JPanel getUpPanel() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.MAIN_BACK_COLOR); panelUp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); JLabel labelTitle = new JLabel(PropertyUtil.getProperty("ds.ui.database.title")); labelTitle.setFont(UiConsts.FONT_TITLE); labelTitle.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.add(labelTitle); return panelUp; } /** * 面板中部 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new BorderLayout()); // 数据库列表Panel JPanel panelList = new JPanel(); Dimension preferredSize = new Dimension(245, UiConsts.MAIN_WINDOW_HEIGHT); panelList.setPreferredSize(preferredSize); panelList.setBackground(new Color(62, 62, 62)); panelList.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); panelFrom = new JPanel(); panelFrom.setBackground(new Color(69, 186, 121)); panelFrom.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 13)); Dimension preferredSizeListItem = new Dimension(245, 48); panelFrom.setPreferredSize(preferredSizeListItem); panelTo = new JPanel(); panelTo.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); panelTo.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 13)); panelTo.setPreferredSize(preferredSizeListItem); JLabel labelFrom = new JLabel(PropertyUtil.getProperty("ds.ui.database.label.from")); JLabel labelTo = new JLabel(PropertyUtil.getProperty("ds.ui.database.label.to")); Font fontListItem = new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 15); labelFrom.setFont(fontListItem); labelTo.setFont(fontListItem); labelFrom.setForeground(Color.white); labelTo.setForeground(Color.white); panelFrom.add(labelFrom); panelTo.add(labelTo); panelList.add(panelFrom); panelList.add(panelTo); // 数据库设置Panel databaseSettingPanel = new JPanel(); databaseSettingPanel.setBackground(UiConsts.MAIN_BACK_COLOR); databaseSettingPanel.setLayout(new BorderLayout()); databaseSettingPanel.add(databaseSettingPanelFrom); panelCenter.add(panelList, BorderLayout.WEST); panelCenter.add(databaseSettingPanel, BorderLayout.CENTER); return panelCenter; } /** * 添加相关组件的事件监听 */ private void addListener() { panelFrom.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { panelFrom.setBackground(new Color(69, 186, 121)); panelTo.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); DatabasePanel.databaseSettingPanel.removeAll(); DatabasePanelFrom.setContent(); DatabasePanel.databaseSettingPanel.add(databaseSettingPanelFrom); App.databasePanel.updateUI(); } }); panelTo.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { panelTo.setBackground(new Color(69, 186, 121)); panelFrom.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); DatabasePanel.databaseSettingPanel.removeAll(); DatabasePanelTo.setContent(); DatabasePanel.databaseSettingPanel.add(databaseSettingPanelTo); App.databasePanel.updateUI(); } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/DatabasePanelFrom.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.DESPlus; import com.luoboduner.wesync.tools.DbUtilSQLServer; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.sql.Connection; /** * 来源数据库面板 * * @author Bob */ public class DatabasePanelFrom extends JPanel { private static final long serialVersionUID = 1L; private static MyIconButton buttonTestLink; private static MyIconButton buttonSave; private static JTextField textFieldDatabaseHost; private static JTextField textFieldDatabaseName; private static JTextField textFieldDatabaseUser; private static JPasswordField passwordFieldDatabasePassword; private static final Logger logger = LoggerFactory.getLogger(DatabasePanelFrom.class); /** * 构造 */ public DatabasePanelFrom() { initialize(); addComponent(); setContent(); addListener(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(2, 1)); // 设置Grid JPanel panelGridSetting = new JPanel(); panelGridSetting.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridSetting.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 JLabel labelDatabaseType = new JLabel(PropertyUtil.getProperty("ds.ui.database.type")); JLabel labelDatabaseHost = new JLabel(PropertyUtil.getProperty("ds.ui.database.host")); JLabel labelDatabaseName = new JLabel(PropertyUtil.getProperty("ds.ui.database.name")); JLabel labelDatabaseUser = new JLabel(PropertyUtil.getProperty("ds.ui.database.user")); JLabel labelDatabasePassword = new JLabel(PropertyUtil.getProperty("ds.ui.database.password")); JComboBox comboxDatabaseType = new JComboBox(); comboxDatabaseType.addItem("SQL Server"); comboxDatabaseType.setEditable(false); textFieldDatabaseHost = new JTextField(); textFieldDatabaseName = new JTextField(); textFieldDatabaseUser = new JTextField(); passwordFieldDatabasePassword = new JPasswordField(); // 字体 labelDatabaseType.setFont(UiConsts.FONT_NORMAL); labelDatabaseHost.setFont(UiConsts.FONT_NORMAL); labelDatabaseName.setFont(UiConsts.FONT_NORMAL); labelDatabaseUser.setFont(UiConsts.FONT_NORMAL); labelDatabasePassword.setFont(UiConsts.FONT_NORMAL); comboxDatabaseType.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseHost.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseName.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseUser.setFont(UiConsts.FONT_NORMAL); passwordFieldDatabasePassword.setFont(UiConsts.FONT_NORMAL); // 大小 labelDatabaseType.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseHost.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseName.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseUser.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabasePassword.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); comboxDatabaseType.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseHost.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseName.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseUser.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); passwordFieldDatabasePassword.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); // 组合元素 panelGridSetting.add(labelDatabaseType); panelGridSetting.add(comboxDatabaseType); panelGridSetting.add(labelDatabaseHost); panelGridSetting.add(textFieldDatabaseHost); panelGridSetting.add(labelDatabaseName); panelGridSetting.add(textFieldDatabaseName); panelGridSetting.add(labelDatabaseUser); panelGridSetting.add(textFieldDatabaseUser); panelGridSetting.add(labelDatabasePassword); panelGridSetting.add(passwordFieldDatabasePassword); panelCenter.add(panelGridSetting); return panelCenter; } /** * 底部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 15)); buttonTestLink = new MyIconButton(UiConsts.ICON_TEST_LINK, UiConsts.ICON_TEST_LINK_ENABLE, UiConsts.ICON_TEST_LINK_DISABLE, ""); buttonSave = new MyIconButton(UiConsts.ICON_SAVE, UiConsts.ICON_SAVE_ENABLE, UiConsts.ICON_SAVE_DISABLE, ""); panelDown.add(buttonTestLink); panelDown.add(buttonSave); return panelDown; } /** * 设置文本区内容 */ public static void setContent() { textFieldDatabaseHost.setText(ConstantsTools.CONFIGER.getHostFrom()); textFieldDatabaseName.setText(ConstantsTools.CONFIGER.getNameFrom()); String password = ""; String user = ""; try { DESPlus des = new DESPlus(); password = des.decrypt(ConstantsTools.CONFIGER.getPasswordFrom()); user = des.decrypt(ConstantsTools.CONFIGER.getUserFrom()); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.from.err.decode") + e.toString()); e.printStackTrace(); } textFieldDatabaseUser.setText(user); passwordFieldDatabasePassword.setText(password); } /** * 为相关组件添加事件监听 */ private void addListener() { buttonSave.addActionListener(e -> { try { ConstantsTools.CONFIGER.setHostFrom(textFieldDatabaseHost.getText()); ConstantsTools.CONFIGER.setNameFrom(textFieldDatabaseName.getText()); String password = ""; String user = ""; try { DESPlus des = new DESPlus(); user = des.encrypt(textFieldDatabaseUser.getText()); password = des.encrypt(new String(passwordFieldDatabasePassword.getPassword())); } catch (Exception e1) { logger.error(PropertyUtil.getProperty("ds.ui.database.from.err.encode") + e1.toString()); e1.printStackTrace(); } ConstantsTools.CONFIGER.setUserFrom(user); ConstantsTools.CONFIGER.setPasswordFrom(password); JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.save.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } catch (Exception e1) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.save.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); logger.error("Write to xml file error" + e1.toString()); } }); buttonTestLink.addActionListener(e -> { try { DbUtilSQLServer dbSQLServer = DbUtilSQLServer.getInstance(); String dburl = textFieldDatabaseHost.getText(); String dbname = textFieldDatabaseName.getText(); String dbuser = textFieldDatabaseUser.getText(); String dbpassword = new String(passwordFieldDatabasePassword.getPassword()); Connection conn = dbSQLServer.testConnection(dburl, dbname, dbuser, dbpassword); if (conn == null) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.fail"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } } catch (Exception e1) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.fail") + "\n" + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/DatabasePanelTo.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.DESPlus; import com.luoboduner.wesync.tools.DbUtilMySQL; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.sql.Connection; /** * 目标数据库面板 * * @author Bob */ public class DatabasePanelTo extends JPanel { private static final long serialVersionUID = 1L; private static MyIconButton buttonTestLink; private static MyIconButton buttonSave; private static JTextField textFieldDatabaseHost; private static JTextField textFieldDatabaseName; private static JTextField textFieldDatabaseUser; private static JPasswordField passwordFieldDatabasePassword; private static final Logger logger = LoggerFactory.getLogger(DatabasePanelTo.class); /** * 构造 */ public DatabasePanelTo() { initialize(); addComponent(); setContent(); addListener(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(2, 1)); // 设置Grid JPanel panelGridSetting = new JPanel(); panelGridSetting.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridSetting.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 JLabel labelDatabaseType = new JLabel(PropertyUtil.getProperty("ds.ui.database.type")); JLabel labelDatabaseHost = new JLabel(PropertyUtil.getProperty("ds.ui.database.host")); JLabel labelDatabaseName = new JLabel(PropertyUtil.getProperty("ds.ui.database.name")); JLabel labelDatabaseUser = new JLabel(PropertyUtil.getProperty("ds.ui.database.user")); JLabel labelDatabasePassword = new JLabel(PropertyUtil.getProperty("ds.ui.database.password")); JComboBox comboxDatabaseType = new JComboBox(); comboxDatabaseType.addItem("MySQL"); comboxDatabaseType.setEditable(false); textFieldDatabaseHost = new JTextField(); textFieldDatabaseName = new JTextField(); textFieldDatabaseUser = new JTextField(); passwordFieldDatabasePassword = new JPasswordField(); // 字体 labelDatabaseType.setFont(UiConsts.FONT_NORMAL); labelDatabaseHost.setFont(UiConsts.FONT_NORMAL); labelDatabaseName.setFont(UiConsts.FONT_NORMAL); labelDatabaseUser.setFont(UiConsts.FONT_NORMAL); labelDatabasePassword.setFont(UiConsts.FONT_NORMAL); comboxDatabaseType.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseHost.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseName.setFont(UiConsts.FONT_NORMAL); textFieldDatabaseUser.setFont(UiConsts.FONT_NORMAL); passwordFieldDatabasePassword.setFont(UiConsts.FONT_NORMAL); // 大小 labelDatabaseType.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseHost.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseName.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabaseUser.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); labelDatabasePassword.setPreferredSize(UiConsts.LABLE_SIZE_ITEM); comboxDatabaseType.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseHost.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseName.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); textFieldDatabaseUser.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); passwordFieldDatabasePassword.setPreferredSize(UiConsts.TEXT_FIELD_SIZE_ITEM); // 组合元素 panelGridSetting.add(labelDatabaseType); panelGridSetting.add(comboxDatabaseType); panelGridSetting.add(labelDatabaseHost); panelGridSetting.add(textFieldDatabaseHost); panelGridSetting.add(labelDatabaseName); panelGridSetting.add(textFieldDatabaseName); panelGridSetting.add(labelDatabaseUser); panelGridSetting.add(textFieldDatabaseUser); panelGridSetting.add(labelDatabasePassword); panelGridSetting.add(passwordFieldDatabasePassword); panelCenter.add(panelGridSetting); return panelCenter; } /** * 底部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 15)); buttonTestLink = new MyIconButton(UiConsts.ICON_TEST_LINK, UiConsts.ICON_TEST_LINK_ENABLE, UiConsts.ICON_TEST_LINK_DISABLE, ""); buttonSave = new MyIconButton(UiConsts.ICON_SAVE, UiConsts.ICON_SAVE_ENABLE, UiConsts.ICON_SAVE_DISABLE, ""); panelDown.add(buttonTestLink); panelDown.add(buttonSave); return panelDown; } /** * 设置文本区内容 */ public static void setContent() { textFieldDatabaseHost.setText(ConstantsTools.CONFIGER.getHostTo()); textFieldDatabaseName.setText(ConstantsTools.CONFIGER.getNameTo()); String user = ""; String password = ""; try { DESPlus des = new DESPlus(); user = des.decrypt(ConstantsTools.CONFIGER.getUserTo()); password = des.decrypt(ConstantsTools.CONFIGER.getPasswordTo()); } catch (Exception e) { logger.error(PropertyUtil.getProperty("ds.ui.database.to.err.decode") + e.toString()); e.printStackTrace(); } textFieldDatabaseUser.setText(user); passwordFieldDatabasePassword.setText(password); } /** * 为相关组件添加事件监听 */ private void addListener() { buttonSave.addActionListener(e -> { try { ConstantsTools.CONFIGER.setHostTo(textFieldDatabaseHost.getText()); ConstantsTools.CONFIGER.setNameTo(textFieldDatabaseName.getText()); String password = ""; String user = ""; try { DESPlus des = new DESPlus(); user = des.encrypt(textFieldDatabaseUser.getText()); password = des.encrypt(new String(passwordFieldDatabasePassword.getPassword())); } catch (Exception e1) { logger.error(PropertyUtil.getProperty("ds.ui.database.to.err.encode") + e1.toString()); e1.printStackTrace(); } ConstantsTools.CONFIGER.setUserTo(user); ConstantsTools.CONFIGER.setPasswordTo(password); JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.save.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } catch (Exception e1) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.save.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); logger.error("Write to xml file error" + e1.toString()); } }); buttonTestLink.addActionListener(e -> { try { DbUtilMySQL dbMySQL = DbUtilMySQL.getInstance(); String dburl = textFieldDatabaseHost.getText(); String dbname = textFieldDatabaseName.getText(); String dbuser = textFieldDatabaseUser.getText(); String dbpassword = new String(passwordFieldDatabasePassword.getPassword()); Connection conn = dbMySQL.testConnection(dburl, dbname, dbuser, dbpassword); if (conn == null) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.fail"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } } catch (Exception e1) { JOptionPane.showMessageDialog(App.databasePanel, PropertyUtil.getProperty("ds.ui.database.err.link.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/SchedulePanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.PropertyUtil; import com.luoboduner.wesync.tools.Utils; import javax.swing.*; import java.awt.*; /** * 计划任务面板 * * @author Bob */ public class SchedulePanel extends JPanel { private static final long serialVersionUID = 1L; private static MyIconButton buttonSave; private static JRadioButton radio5Min, radio15Min, radio30Min, radioPerHour, radioPerDay, radioPerWeek, radioEveryDay; private static JTextField fixedTime; private static final Logger logger = LoggerFactory.getLogger(SchedulePanel.class); /** * 构造 */ public SchedulePanel() { initialize(); addComponent(); addListener(); setCurrentSchedule(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getUpPanel(), BorderLayout.NORTH); this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 上部面板 * * @return */ private JPanel getUpPanel() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.MAIN_BACK_COLOR); panelUp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); JLabel labelTitle = new JLabel(PropertyUtil.getProperty("ds.ui.schedule.title")); labelTitle.setFont(UiConsts.FONT_TITLE); labelTitle.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.add(labelTitle); return panelUp; } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(1, 1)); // 计划时间Grid JPanel panelGridSchedule = new JPanel(); panelGridSchedule.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridSchedule.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 radio5Min = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio1")); radio15Min = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio2")); radio30Min = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio3")); radioPerHour = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio4")); radioPerDay = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio5")); radioPerWeek = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio6")); radioEveryDay = new JRadioButton(PropertyUtil.getProperty("ds.ui.schedule.radio7")); fixedTime = new JTextField(); // 字体 radio5Min.setFont(UiConsts.FONT_RADIO); radio15Min.setFont(UiConsts.FONT_RADIO); radio30Min.setFont(UiConsts.FONT_RADIO); radioPerHour.setFont(UiConsts.FONT_RADIO); radioPerDay.setFont(UiConsts.FONT_RADIO); radioPerWeek.setFont(UiConsts.FONT_RADIO); radioEveryDay.setFont(UiConsts.FONT_RADIO); fixedTime.setFont(UiConsts.FONT_RADIO); // 颜色 radio5Min.setBackground(UiConsts.MAIN_BACK_COLOR); radio15Min.setBackground(UiConsts.MAIN_BACK_COLOR); radio30Min.setBackground(UiConsts.MAIN_BACK_COLOR); radioPerHour.setBackground(UiConsts.MAIN_BACK_COLOR); radioPerDay.setBackground(UiConsts.MAIN_BACK_COLOR); radioPerWeek.setBackground(UiConsts.MAIN_BACK_COLOR); radioEveryDay.setBackground(UiConsts.MAIN_BACK_COLOR); fixedTime.setBackground(UiConsts.MAIN_BACK_COLOR); // 大小 radio5Min.setMinimumSize(UiConsts.RADIO_SIZE); radio15Min.setPreferredSize(UiConsts.RADIO_SIZE); radio30Min.setMinimumSize(UiConsts.RADIO_SIZE); radioPerHour.setPreferredSize(UiConsts.RADIO_SIZE); radioPerDay.setMinimumSize(UiConsts.RADIO_SIZE); radioPerWeek.setPreferredSize(UiConsts.RADIO_SIZE); radioEveryDay.setMinimumSize(UiConsts.RADIO_SIZE); Dimension preferredSize = new Dimension(130, 26); fixedTime.setPreferredSize(preferredSize); // 组合元素 panelGridSchedule.add(radio5Min); panelGridSchedule.add(radio15Min); panelGridSchedule.add(radio30Min); panelGridSchedule.add(radioPerHour); panelGridSchedule.add(radioPerDay); panelGridSchedule.add(radioPerWeek); panelGridSchedule.add(radioEveryDay); panelGridSchedule.add(fixedTime); panelCenter.add(panelGridSchedule); return panelCenter; } /** * 下部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 15)); buttonSave = new MyIconButton(UiConsts.ICON_SAVE, UiConsts.ICON_SAVE_ENABLE, UiConsts.ICON_SAVE_DISABLE, ""); panelDown.add(buttonSave); return panelDown; } /** * 设置当前的radio状态 */ public void setCurrentSchedule() { String[] indexs = ConstantsTools.CONFIGER.getSchedule().split(","); radio5Min.setSelected(Boolean.parseBoolean(indexs[0])); radio15Min.setSelected(Boolean.parseBoolean(indexs[1])); radio30Min.setSelected(Boolean.parseBoolean(indexs[2])); radioPerHour.setSelected(Boolean.parseBoolean(indexs[3])); radioPerDay.setSelected(Boolean.parseBoolean(indexs[4])); radioPerWeek.setSelected(Boolean.parseBoolean(indexs[5])); radioEveryDay.setSelected(Boolean.parseBoolean(indexs[6])); fixedTime.setText(ConstantsTools.CONFIGER.getScheduleFixTime()); } /** * 为各组件添加事件监听 */ public void addListener() { radio5Min.addActionListener(e -> { radio5Min.setSelected(true); radio15Min.setSelected(false); radio30Min.setSelected(false); radioPerHour.setSelected(false); radioPerDay.setSelected(false); radioPerWeek.setSelected(false); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radio15Min.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(true); radio30Min.setSelected(false); radioPerHour.setSelected(false); radioPerDay.setSelected(false); radioPerWeek.setSelected(false); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radio30Min.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(false); radio30Min.setSelected(true); radioPerHour.setSelected(false); radioPerDay.setSelected(false); radioPerWeek.setSelected(false); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radioPerHour.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(false); radio30Min.setSelected(false); radioPerHour.setSelected(true); radioPerDay.setSelected(false); radioPerWeek.setSelected(false); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radioPerDay.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(false); radio30Min.setSelected(false); radioPerHour.setSelected(false); radioPerDay.setSelected(true); radioPerWeek.setSelected(false); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radioPerWeek.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(false); radio30Min.setSelected(false); radioPerHour.setSelected(false); radioPerDay.setSelected(false); radioPerWeek.setSelected(true); radioEveryDay.setSelected(false); App.schedulePanel.updateUI(); }); radioEveryDay.addActionListener(e -> { radio5Min.setSelected(false); radio15Min.setSelected(false); radio30Min.setSelected(false); radioPerHour.setSelected(false); radioPerDay.setSelected(false); radioPerWeek.setSelected(false); radioEveryDay.setSelected(true); App.schedulePanel.updateUI(); }); buttonSave.addActionListener(e -> { StringBuffer index = new StringBuffer(); // radio5Min, radioPerHour, radioPerDay, radioPerWeek; index.append(radio5Min.isSelected()).append(","); index.append(radio15Min.isSelected()).append(","); index.append(radio30Min.isSelected()).append(","); index.append(radioPerHour.isSelected()).append(","); index.append(radioPerDay.isSelected()).append(","); index.append(radioPerWeek.isSelected()).append(","); index.append(radioEveryDay.isSelected()); try { ConstantsTools.CONFIGER.setSchedule(index.toString()); ConstantsTools.CONFIGER.setScheduleFixTime(fixedTime.getText()); JOptionPane.showMessageDialog(App.schedulePanel, PropertyUtil.getProperty("ds.ui.schedule.saveTips"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); if (!StatusPanel.buttonStartSchedule.isEnabled()) { // 设置显示下一次执行时间 StatusPanel.labelNextTime.setText(PropertyUtil.getProperty("ds.ui.schedule.nextTime") + Utils.getNextSyncTime()); } } catch (Exception e1) { JOptionPane.showMessageDialog(App.schedulePanel, PropertyUtil.getProperty("ds.ui.save.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); logger.error("Write to xml file error" + e1.toString()); } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/SettingPanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; /** * 设置面板 * * @author Bob */ public class SettingPanel extends JPanel { private static final long serialVersionUID = 1L; private static JPanel panelOption; private static JPanel panelAbout; public static JPanel settingPanelMain; private static JPanel settingPanelOption; private static JPanel settingPanelAbout; /** * 构造 */ public SettingPanel() { initialize(); addComponent(); addListener(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); settingPanelOption = new SettingPanelOption(); settingPanelAbout = new SettingPanelAbout(); } /** * 添加组件 */ private void addComponent() { this.add(getUpPanel(), BorderLayout.NORTH); this.add(getCenterPanel(), BorderLayout.CENTER); } /** * 上部面板 * * @return */ private JPanel getUpPanel() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.MAIN_BACK_COLOR); panelUp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); JLabel labelTitle = new JLabel(PropertyUtil.getProperty("ds.ui.setting.title")); labelTitle.setFont(UiConsts.FONT_TITLE); labelTitle.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.add(labelTitle); return panelUp; } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new BorderLayout()); // 列表Panel JPanel panelList = new JPanel(); Dimension preferredSize = new Dimension(245, UiConsts.MAIN_WINDOW_HEIGHT); panelList.setPreferredSize(preferredSize); panelList.setBackground(new Color(62, 62, 62)); panelList.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); panelOption = new JPanel(); panelOption.setBackground(new Color(69, 186, 121)); panelOption.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 13)); Dimension preferredSizeListItem = new Dimension(245, 48); panelOption.setPreferredSize(preferredSizeListItem); panelAbout = new JPanel(); panelAbout.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); panelAbout.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 13)); panelAbout.setPreferredSize(preferredSizeListItem); JLabel labelOption = new JLabel(PropertyUtil.getProperty("ds.ui.setting.option")); JLabel labelAbout = new JLabel(PropertyUtil.getProperty("ds.ui.setting.about")); Font fontListItem = new Font(PropertyUtil.getProperty("ds.ui.font.family"), 0, 15); labelOption.setFont(fontListItem); labelAbout.setFont(fontListItem); labelOption.setForeground(Color.white); labelAbout.setForeground(Color.white); panelOption.add(labelOption); panelAbout.add(labelAbout); panelList.add(panelOption); panelList.add(panelAbout); // 设置Panel settingPanelMain = new JPanel(); settingPanelMain.setBackground(UiConsts.MAIN_BACK_COLOR); settingPanelMain.setLayout(new BorderLayout()); settingPanelMain.add(settingPanelOption); panelCenter.add(panelList, BorderLayout.WEST); panelCenter.add(settingPanelMain, BorderLayout.CENTER); return panelCenter; } /** * 为相关组件添加事件监听 */ private void addListener() { panelOption.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { panelOption.setBackground(new Color(69, 186, 121)); panelAbout.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); SettingPanel.settingPanelMain.removeAll(); SettingPanelOption.setCurrentOption(); SettingPanel.settingPanelMain.add(settingPanelOption); App.settingPanel.updateUI(); } }); panelAbout.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { panelAbout.setBackground(new Color(69, 186, 121)); panelOption.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); SettingPanel.settingPanelMain.removeAll(); SettingPanel.settingPanelMain.add(settingPanelAbout); App.settingPanel.updateUI(); } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/SettingPanelAbout.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; /** * 关于面板 * * @author Bob */ public class SettingPanelAbout extends JPanel { private static final long serialVersionUID = 1L; /** * 构造 */ public SettingPanelAbout() { initialize(); addComponent(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(3, 1)); // 图标、版本Grid JPanel panelGridIcon = new JPanel(); panelGridIcon.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridIcon.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 MyIconButton icon = new MyIconButton(UiConsts.ICON_DATA_SYNC, UiConsts.ICON_DATA_SYNC, UiConsts.ICON_DATA_SYNC, ""); JLabel labelName = new JLabel(UiConsts.APP_NAME); JLabel labelVersion = new JLabel(UiConsts.APP_VERSION); // 字体 labelName.setFont(UiConsts.FONT_NORMAL); labelVersion.setFont(UiConsts.FONT_NORMAL); // 大小 Dimension size = new Dimension(200, 30); labelName.setPreferredSize(size); labelVersion.setPreferredSize(size); // 组合元素 panelGridIcon.add(icon); panelGridIcon.add(labelName); panelGridIcon.add(labelVersion); // 建议帮助 Grid JPanel panelGridHelp = new JPanel(); panelGridHelp.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridHelp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 JLabel labelAdvice = new JLabel(PropertyUtil.getProperty("ds.ui.app.advice")); JLabel labelHelp = new JLabel(PropertyUtil.getProperty("ds.ui.app.help")); // 字体 labelAdvice.setFont(UiConsts.FONT_NORMAL); labelHelp.setFont(UiConsts.FONT_NORMAL); // 大小 labelAdvice.setPreferredSize(UiConsts.LABLE_SIZE); labelHelp.setPreferredSize(UiConsts.LABLE_SIZE); // 组合元素 panelGridHelp.add(labelAdvice); panelGridHelp.add(labelHelp); panelCenter.add(panelGridIcon); // panelCenter.add(panelGridHelp); return panelCenter; } /** * 底部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 15)); JLabel labelInfo = new JLabel(PropertyUtil.getProperty("ds.ui.app.info")); labelInfo.setFont(UiConsts.FONT_NORMAL); labelInfo.setForeground(Color.gray); panelDown.add(labelInfo); return panelDown; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/SettingPanelOption.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import com.luoboduner.wesync.logic.ConstantsLogic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; /** * 高级选项面板 * * @author Bob */ public class SettingPanelOption extends JPanel { private static final long serialVersionUID = 1L; private static MyIconButton buttonSave; private static MyIconButton buttionTableFiled; private static MyIconButton buttionClearLogs; private static JCheckBox checkBoxAutoBak; private static JCheckBox checkBoxDebug; private static JCheckBox checkBoxStrict; private static JTextField textField; private static final Logger logger = LoggerFactory.getLogger(SettingPanelOption.class); /** * 构造 */ public SettingPanelOption() { initialize(); addComponent(); setCurrentOption(); addListener(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(1, 1)); // 设置Grid JPanel panelGridOption = new JPanel(); panelGridOption.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridOption.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); // 初始化组件 JPanel panelItem1 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem2 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem3 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem4 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem5 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem6 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JPanel panelItem7 = new JPanel(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); panelItem1.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem2.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem3.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem4.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem5.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem6.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem7.setBackground(UiConsts.MAIN_BACK_COLOR); panelItem1.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem2.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem3.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem4.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem5.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem6.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); panelItem7.setPreferredSize(UiConsts.PANEL_ITEM_SIZE); // 各Item buttionTableFiled = new MyIconButton(UiConsts.ICON_TABLE_FIELD, UiConsts.ICON_TABLE_FIELD_ENABLE, UiConsts.ICON_TABLE_FIELD_DISABLE, ""); panelItem1.add(buttionTableFiled); buttionClearLogs = new MyIconButton(UiConsts.ICON_CLEAR_LOG, UiConsts.ICON_CLEAR_LOG_ENABLE, UiConsts.ICON_CLEAR_LOG_DISABLE, ""); panelItem2.add(buttionClearLogs); MyIconButton buttionClearBaks = new MyIconButton(UiConsts.ICON_CLEAR_ALL_BAKS, UiConsts.ICON_CLEAR_ALL_BAKS_ENABLE, UiConsts.ICON_CLEAR_ALL_BAKS_DISABLE, ""); panelItem3.add(buttionClearBaks); checkBoxAutoBak = new JCheckBox(PropertyUtil.getProperty("ds.ui.setting.autoBackUp")); checkBoxAutoBak.setBackground(UiConsts.MAIN_BACK_COLOR); checkBoxAutoBak.setFont(UiConsts.FONT_RADIO); panelItem4.add(checkBoxAutoBak); JLabel label = new JLabel(PropertyUtil.getProperty("ds.ui.setting.mysqlPath")); textField = new JTextField(); label.setBackground(UiConsts.MAIN_BACK_COLOR); label.setFont(UiConsts.FONT_RADIO); textField.setFont(UiConsts.FONT_RADIO); Dimension dm = new Dimension(334, 26); textField.setPreferredSize(dm); panelItem5.add(label); panelItem5.add(textField); checkBoxStrict = new JCheckBox(PropertyUtil.getProperty("ds.ui.setting.strict")); checkBoxStrict.setBackground(UiConsts.MAIN_BACK_COLOR); checkBoxStrict.setFont(UiConsts.FONT_RADIO); panelItem6.add(checkBoxStrict); checkBoxDebug = new JCheckBox(PropertyUtil.getProperty("ds.ui.setting.debugMode")); checkBoxDebug.setBackground(UiConsts.MAIN_BACK_COLOR); checkBoxDebug.setFont(UiConsts.FONT_RADIO); panelItem7.add(checkBoxDebug); // 组合元素 panelGridOption.add(panelItem1); panelGridOption.add(panelItem2); panelGridOption.add(panelItem3); panelGridOption.add(panelItem4); panelGridOption.add(panelItem5); panelGridOption.add(panelItem6); panelGridOption.add(panelItem7); panelCenter.add(panelGridOption); return panelCenter; } /** * 底部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 15)); buttonSave = new MyIconButton(UiConsts.ICON_SAVE, UiConsts.ICON_SAVE_ENABLE, UiConsts.ICON_SAVE_DISABLE, ""); panelDown.add(buttonSave); return panelDown; } /** * 设置当前combox选项状态 */ public static void setCurrentOption() { checkBoxAutoBak.setSelected(Boolean.parseBoolean(ConstantsTools.CONFIGER.getAutoBak())); checkBoxDebug.setSelected(Boolean.parseBoolean(ConstantsTools.CONFIGER.getDebugMode())); checkBoxStrict.setSelected(Boolean.parseBoolean(ConstantsTools.CONFIGER.getStrictMode())); textField.setText(ConstantsTools.CONFIGER.getMysqlPath()); } /** * 为相关组件添加事件监听 */ private void addListener() { buttonSave.addActionListener(e -> { try { ConstantsTools.CONFIGER.setAutoBak(String.valueOf(checkBoxAutoBak.isSelected())); ConstantsTools.CONFIGER.setDebugMode(String.valueOf(checkBoxDebug.isSelected())); ConstantsTools.CONFIGER.setStrictMode(String.valueOf(checkBoxStrict.isSelected())); ConstantsTools.CONFIGER.setMysqlPath(textField.getText()); JOptionPane.showMessageDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.save.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } catch (Exception e1) { JOptionPane.showMessageDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.save.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); logger.error("Write to xml file error" + e1.toString()); } }); buttionTableFiled.addActionListener(e -> { try { Desktop.getDesktop().open(new File(ConstantsLogic.TABLE_FIELD_DIR)); } catch (IOException e1) { logger.error("open table_field file fail:" + e1.toString()); e1.printStackTrace(); } }); buttionClearLogs.addActionListener(e -> { int answer = JOptionPane.showConfirmDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.setting.clean.makeSure"), PropertyUtil.getProperty("ds.ui.tips"), 2); if (answer == 0) { FileOutputStream testfile = null; try { testfile = new FileOutputStream(ConstantsTools.PATH_LOG); testfile.write(new String("").getBytes()); testfile.flush(); JOptionPane.showMessageDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.setting.clean.success"), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.PLAIN_MESSAGE); } catch (IOException e1) { JOptionPane.showMessageDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.setting.clean.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); e1.printStackTrace(); } finally { if (testfile != null) { try { testfile.close(); } catch (IOException e1) { JOptionPane.showMessageDialog(App.settingPanel, PropertyUtil.getProperty("ds.ui.setting.clean.fail") + e1.getMessage(), PropertyUtil.getProperty("ds.ui.tips"), JOptionPane.ERROR_MESSAGE); e1.printStackTrace(); } } } } }); } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/StatusPanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import com.luoboduner.wesync.logic.ExecuteThread; import com.luoboduner.wesync.logic.ScheduleExecuteThread; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.luoboduner.wesync.tools.ConstantsTools; import com.luoboduner.wesync.tools.PropertyUtil; import com.luoboduner.wesync.tools.StatusLog; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 状态面板 * * @author Bob */ public class StatusPanel extends JPanel { private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory.getLogger(StatusPanel.class); public static MyIconButton buttonStartSchedule; public static MyIconButton buttonStop; public static MyIconButton buttonStartNow; public static JProgressBar progressTotal; public static JProgressBar progressCurrent; public static JLabel labelStatus; public static JLabel labelStatusDetail; public static JLabel labelFrom; public static JLabel labelTo; public static JLabel labelLastTime; public static JLabel labelKeepTime; public static JLabel labelNextTime; public static JLabel labelSuccess; public static JLabel labelFail; private static JLabel labelLog; private static ScheduledExecutorService service; public static boolean isRunning = false; /** * 构造 */ public StatusPanel() { super(true); initialize(); addComponent(); setContent(); addListener(); } /** * 初始化 */ private void initialize() { this.setBackground(UiConsts.MAIN_BACK_COLOR); this.setLayout(new BorderLayout()); } /** * 添加组件 */ private void addComponent() { this.add(getUpPanel(), BorderLayout.NORTH); this.add(getCenterPanel(), BorderLayout.CENTER); this.add(getDownPanel(), BorderLayout.SOUTH); } /** * 上部面板 * * @return */ private JPanel getUpPanel() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.MAIN_BACK_COLOR); panelUp.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 5)); JLabel labelTitle = new JLabel(PropertyUtil.getProperty("ds.ui.status.title")); labelTitle.setFont(UiConsts.FONT_TITLE); labelTitle.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.add(labelTitle); return panelUp; } /** * 中部面板 * * @return */ private JPanel getCenterPanel() { // 中间面板 JPanel panelCenter = new JPanel(); panelCenter.setBackground(UiConsts.MAIN_BACK_COLOR); panelCenter.setLayout(new GridLayout(4, 1)); // 状态Grid JPanel panelGridStatus = new JPanel(); panelGridStatus.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridStatus.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); labelStatus = new JLabel(PropertyUtil.getProperty("ds.ui.status.ready")); labelStatusDetail = new JLabel(PropertyUtil.getProperty("ds.ui.status.detail")); labelStatus.setFont(new Font(PropertyUtil.getProperty("ds.ui.font.family"), 1, 15)); labelStatusDetail.setFont(UiConsts.FONT_NORMAL); labelStatus.setPreferredSize(UiConsts.LABLE_SIZE); labelStatusDetail.setPreferredSize(UiConsts.LABLE_SIZE); panelGridStatus.add(labelStatus); panelGridStatus.add(labelStatusDetail); // 来源/目标 Grid JPanel panelGridFromTo = new JPanel(); panelGridFromTo.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridFromTo.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); labelFrom = new JLabel(); labelTo = new JLabel(); labelFrom.setFont(UiConsts.FONT_NORMAL); labelTo.setFont(UiConsts.FONT_NORMAL); labelFrom.setPreferredSize(UiConsts.LABLE_SIZE); labelTo.setPreferredSize(UiConsts.LABLE_SIZE); panelGridFromTo.add(labelFrom); panelGridFromTo.add(labelTo); // 详情Grid JPanel panelGridDetail = new JPanel(); panelGridDetail.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridDetail.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); labelLastTime = new JLabel(); labelKeepTime = new JLabel(); labelNextTime = new JLabel(); labelNextTime.setText(PropertyUtil.getProperty("ds.ui.schedule.nextTime")); labelSuccess = new JLabel(); labelFail = new JLabel(); labelLog = new JLabel(PropertyUtil.getProperty("ds.ui.status.logDetail")); labelLastTime.setFont(UiConsts.FONT_NORMAL); labelKeepTime.setFont(UiConsts.FONT_NORMAL); labelNextTime.setFont(UiConsts.FONT_NORMAL); labelSuccess.setFont(UiConsts.FONT_NORMAL); labelFail.setFont(UiConsts.FONT_NORMAL); labelLog.setFont(UiConsts.FONT_NORMAL); labelLastTime.setPreferredSize(new Dimension(240, 30)); labelKeepTime.setPreferredSize(new Dimension(300, 30)); labelNextTime.setPreferredSize(UiConsts.LABLE_SIZE); labelSuccess.setPreferredSize(new Dimension(240, 30)); labelFail.setPreferredSize(new Dimension(236, 30)); labelLog.setPreferredSize(UiConsts.LABLE_SIZE); labelLog.setForeground(UiConsts.TOOL_BAR_BACK_COLOR); panelGridDetail.add(labelLastTime); panelGridDetail.add(labelKeepTime); panelGridDetail.add(labelNextTime); panelGridDetail.add(labelSuccess); panelGridDetail.add(labelFail); panelGridDetail.add(labelLog); // 进度Grid JPanel panelGridProgress = new JPanel(); panelGridProgress.setBackground(UiConsts.MAIN_BACK_COLOR); panelGridProgress.setLayout(new GridLayout(2, 1, UiConsts.MAIN_H_GAP, 0)); JPanel panelCurrentProgress = new JPanel(); panelCurrentProgress.setBackground(UiConsts.MAIN_BACK_COLOR); panelCurrentProgress.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 20)); JPanel panelTotalProgress = new JPanel(); panelTotalProgress.setBackground(UiConsts.MAIN_BACK_COLOR); panelTotalProgress.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 0)); JLabel labelCurrent = new JLabel(PropertyUtil.getProperty("ds.ui.status.progress.current")); JLabel labelTotal = new JLabel(PropertyUtil.getProperty("ds.ui.status.progress.total")); labelCurrent.setFont(UiConsts.FONT_NORMAL); labelTotal.setFont(UiConsts.FONT_NORMAL); progressCurrent = new JProgressBar(); progressTotal = new JProgressBar(); Dimension preferredSizeLabel = new Dimension(80, 30); labelCurrent.setPreferredSize(preferredSizeLabel); labelTotal.setPreferredSize(preferredSizeLabel); Dimension preferredSizeProgressbar = new Dimension(640, 20); progressCurrent.setPreferredSize(preferredSizeProgressbar); progressTotal.setPreferredSize(preferredSizeProgressbar); panelCurrentProgress.add(labelCurrent); panelCurrentProgress.add(progressCurrent); panelTotalProgress.add(labelTotal); panelTotalProgress.add(progressTotal); panelGridProgress.add(panelCurrentProgress); panelGridProgress.add(panelTotalProgress); panelCenter.add(panelGridStatus); panelCenter.add(panelGridFromTo); panelCenter.add(panelGridDetail); panelCenter.add(panelGridProgress); return panelCenter; } /** * 底部面板 * * @return */ private JPanel getDownPanel() { JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.MAIN_BACK_COLOR); panelDown.setLayout(new GridLayout(1, 2)); JPanel panelGrid1 = new JPanel(); panelGrid1.setBackground(UiConsts.MAIN_BACK_COLOR); panelGrid1.setLayout(new FlowLayout(FlowLayout.LEFT, UiConsts.MAIN_H_GAP, 15)); JPanel panelGrid2 = new JPanel(); panelGrid2.setBackground(UiConsts.MAIN_BACK_COLOR); panelGrid2.setLayout(new FlowLayout(FlowLayout.RIGHT, UiConsts.MAIN_H_GAP, 15)); buttonStartSchedule = new MyIconButton(UiConsts.ICON_START_SCHEDULE, UiConsts.ICON_START_SCHEDULE_ENABLE, UiConsts.ICON_START_SCHEDULE_DISABLE, ""); buttonStop = new MyIconButton(UiConsts.ICON_STOP, UiConsts.ICON_STOP_ENABLE, UiConsts.ICON_STOP_DISABLE, ""); buttonStop.setEnabled(false); buttonStartNow = new MyIconButton(UiConsts.ICON_SYNC_NOW, UiConsts.ICON_SYNC_NOW_ENABLE, UiConsts.ICON_SYNC_NOW_DISABLE, ""); panelGrid1.add(buttonStartSchedule); panelGrid1.add(buttonStop); panelGrid2.add(buttonStartNow); panelDown.add(panelGrid1); panelDown.add(panelGrid2); return panelDown; } /** * 设置状态面板组件内容 */ public static void setContent() { labelFrom.setText( PropertyUtil.getProperty("ds.ui.status.from") + ConstantsTools.CONFIGER.getHostFrom() + "/" + ConstantsTools.CONFIGER.getNameFrom()); labelTo.setText(PropertyUtil.getProperty("ds.ui.status.to") + ConstantsTools.CONFIGER.getHostTo() + "/" + ConstantsTools.CONFIGER.getNameTo()); labelLastTime.setText(PropertyUtil.getProperty("ds.ui.status.lastSync") + ConstantsTools.CONFIGER.getLastSyncTime()); labelKeepTime.setText(PropertyUtil.getProperty("ds.ui.status.keepTime") + ConstantsTools.CONFIGER.getLastKeepTime() + PropertyUtil.getProperty("ds.ui.status.second")); labelSuccess.setText(PropertyUtil.getProperty("ds.ui.status.successTimes") + ConstantsTools.CONFIGER.getSuccessTime()); labelFail.setText(PropertyUtil.getProperty("ds.ui.status.failTimes") + ConstantsTools.CONFIGER.getFailTime()); } /** * 为各组件添加事件监听 */ private void addListener() { buttonStartNow.addActionListener(e -> { if (isRunning == false) { buttonStartNow.setEnabled(false); buttonStartSchedule.setEnabled(false); StatusPanel.setContent(); StatusPanel.progressTotal.setValue(0); StatusPanel.progressCurrent.setValue(0); labelStatus.setText(PropertyUtil.getProperty("ds.ui.status.manu")); ExecuteThread syncThread = new ExecuteThread(); syncThread.start(); } }); buttonStartSchedule.addActionListener(e -> { buttonStartSchedule.setEnabled(false); buttonStop.setEnabled(true); StatusPanel.setContent(); StatusPanel.progressTotal.setValue(0); StatusPanel.progressCurrent.setValue(0); labelStatus.setText(PropertyUtil.getProperty("ds.ui.status.scheduledRunning")); ScheduleExecuteThread syncThread = new ScheduleExecuteThread(); service = Executors.newSingleThreadScheduledExecutor(); // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间 String scheduleConf = ConstantsTools.CONFIGER.getSchedule(); if ("true,false,false,false,false,false,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 5, TimeUnit.MINUTES); } else if ("false,true,false,false,false,false,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 15, TimeUnit.MINUTES); } else if ("false,false,true,false,false,false,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 30, TimeUnit.MINUTES); } else if ("false,false,false,true,false,false,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 1, TimeUnit.HOURS); } else if ("false,false,false,false,true,false,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 1, TimeUnit.DAYS); } else if ("false,false,false,false,false,true,false".equals(scheduleConf)) { service.scheduleAtFixedRate(syncThread, 0, 7, TimeUnit.DAYS); } else if ("false,false,false,false,false,false,true".equals(scheduleConf)) { long oneDay = 24 * 60 * 60 * 1000; long initDelay = getTimeMillis(ConstantsTools.CONFIGER.getScheduleFixTime().trim()) - System.currentTimeMillis(); initDelay = initDelay > 0 ? initDelay : oneDay + initDelay; service.scheduleAtFixedRate(syncThread, initDelay, oneDay, TimeUnit.MILLISECONDS); } }); buttonStop.addActionListener(e -> { buttonStartSchedule.setEnabled(true); StatusPanel.buttonStartNow.setEnabled(true); service.shutdown(); StatusLog.setNextTime(""); labelStatus.setText(PropertyUtil.getProperty("ds.ui.status.ready")); buttonStop.setEnabled(false); }); labelLog.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { labelLog.setCursor(new Cursor(Cursor.HAND_CURSOR)); } @Override public void mouseClicked(MouseEvent e) { try { Desktop.getDesktop().open(new File(UiConsts.CURRENT_DIR + File.separator + "log")); } catch (IOException e1) { // TODO Auto-generated catch block logger.error(e1.toString()); } } }); } /** * 获取指定时间对应的毫秒数 * * @param time "HH:mm:ss" * @return */ private static long getTimeMillis(String time) { try { DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd"); Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time); return curDate.getTime(); } catch (ParseException e) { e.printStackTrace(); } return 0; } } ================================================ FILE: src/main/java/com/luoboduner/wesync/ui/panel/ToolBarPanel.java ================================================ package com.luoboduner.wesync.ui.panel; import com.luoboduner.wesync.App; import com.luoboduner.wesync.ui.UiConsts; import com.luoboduner.wesync.ui.component.MyIconButton; import com.luoboduner.wesync.tools.PropertyUtil; import javax.swing.*; import java.awt.*; /** * 工具栏面板 * * @author Bob */ public class ToolBarPanel extends JPanel { private static final long serialVersionUID = 1L; private static MyIconButton buttonStatus; private static MyIconButton buttonDatabase; private static MyIconButton buttonSchedule; private static MyIconButton buttonBackup; private static MyIconButton buttonSetting; /** * 构造 */ public ToolBarPanel() { initialize(); addButtion(); addListener(); } /** * 初始化 */ private void initialize() { Dimension preferredSize = new Dimension(48, UiConsts.MAIN_WINDOW_HEIGHT); this.setPreferredSize(preferredSize); this.setMaximumSize(preferredSize); this.setMinimumSize(preferredSize); this.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); this.setLayout(new GridLayout(2, 1)); } /** * 添加工具按钮 */ private void addButtion() { JPanel panelUp = new JPanel(); panelUp.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); panelUp.setLayout(new FlowLayout(-2, -2, -4)); JPanel panelDown = new JPanel(); panelDown.setBackground(UiConsts.TOOL_BAR_BACK_COLOR); panelDown.setLayout(new BorderLayout(0, 0)); buttonStatus = new MyIconButton(UiConsts.ICON_STATUS_ENABLE, UiConsts.ICON_STATUS_ENABLE, UiConsts.ICON_STATUS, PropertyUtil.getProperty("ds.ui.status.title")); buttonDatabase = new MyIconButton(UiConsts.ICON_DATABASE, UiConsts.ICON_DATABASE_ENABLE, UiConsts.ICON_DATABASE, PropertyUtil.getProperty("ds.ui.database.title")); buttonSchedule = new MyIconButton(UiConsts.ICON_SCHEDULE, UiConsts.ICON_SCHEDULE_ENABLE, UiConsts.ICON_SCHEDULE, PropertyUtil.getProperty("ds.ui.schedule.title")); buttonBackup = new MyIconButton(UiConsts.ICON_BACKUP, UiConsts.ICON_BACKUP_ENABLE, UiConsts.ICON_BACKUP, PropertyUtil.getProperty("ds.ui.backup.title")); buttonSetting = new MyIconButton(UiConsts.ICON_SETTING, UiConsts.ICON_SETTING_ENABLE, UiConsts.ICON_SETTING, PropertyUtil.getProperty("ds.ui.setting.title")); panelUp.add(buttonStatus); panelUp.add(buttonDatabase); panelUp.add(buttonSchedule); panelUp.add(buttonBackup); panelDown.add(buttonSetting, BorderLayout.SOUTH); this.add(panelUp); this.add(panelDown); } /** * 为各按钮添加事件动作监听 */ private void addListener() { buttonStatus.addActionListener(e -> { buttonStatus.setIcon(UiConsts.ICON_STATUS_ENABLE); buttonDatabase.setIcon(UiConsts.ICON_DATABASE); buttonSchedule.setIcon(UiConsts.ICON_SCHEDULE); buttonBackup.setIcon(UiConsts.ICON_BACKUP); buttonSetting.setIcon(UiConsts.ICON_SETTING); App.mainPanelCenter.removeAll(); StatusPanel.setContent(); App.mainPanelCenter.add(App.statusPanel, BorderLayout.CENTER); App.mainPanelCenter.updateUI(); }); buttonDatabase.addActionListener(e -> { buttonStatus.setIcon(UiConsts.ICON_STATUS); buttonDatabase.setIcon(UiConsts.ICON_DATABASE_ENABLE); buttonSchedule.setIcon(UiConsts.ICON_SCHEDULE); buttonBackup.setIcon(UiConsts.ICON_BACKUP); buttonSetting.setIcon(UiConsts.ICON_SETTING); App.mainPanelCenter.removeAll(); DatabasePanelFrom.setContent(); DatabasePanelTo.setContent(); App.mainPanelCenter.add(App.databasePanel, BorderLayout.CENTER); App.mainPanelCenter.updateUI(); }); buttonSchedule.addActionListener(e -> { buttonStatus.setIcon(UiConsts.ICON_STATUS); buttonDatabase.setIcon(UiConsts.ICON_DATABASE); buttonSchedule.setIcon(UiConsts.ICON_SCHEDULE_ENABLE); buttonBackup.setIcon(UiConsts.ICON_BACKUP); buttonSetting.setIcon(UiConsts.ICON_SETTING); App.mainPanelCenter.removeAll(); App.schedulePanel.setCurrentSchedule(); App.mainPanelCenter.add(App.schedulePanel, BorderLayout.CENTER); App.mainPanelCenter.updateUI(); }); buttonBackup.addActionListener(e -> { buttonStatus.setIcon(UiConsts.ICON_STATUS); buttonDatabase.setIcon(UiConsts.ICON_DATABASE); buttonSchedule.setIcon(UiConsts.ICON_SCHEDULE); buttonBackup.setIcon(UiConsts.ICON_BACKUP_ENABLE); buttonSetting.setIcon(UiConsts.ICON_SETTING); BackupPanel.initTableData(); BackupPanel.tableFrom.validate(); App.mainPanelCenter.removeAll(); App.mainPanelCenter.add(App.backupPanel, BorderLayout.CENTER); App.mainPanelCenter.updateUI(); }); buttonSetting.addActionListener(e -> { buttonStatus.setIcon(UiConsts.ICON_STATUS); buttonDatabase.setIcon(UiConsts.ICON_DATABASE); buttonSchedule.setIcon(UiConsts.ICON_SCHEDULE); buttonBackup.setIcon(UiConsts.ICON_BACKUP); buttonSetting.setIcon(UiConsts.ICON_SETTING_ENABLE); App.mainPanelCenter.removeAll(); SettingPanelOption.setCurrentOption(); App.mainPanelCenter.add(App.settingPanel, BorderLayout.CENTER); App.mainPanelCenter.updateUI(); }); } } ================================================ FILE: src/main/resources/logback.xml ================================================ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n ./logs/WeSync.%d{yyyy-MM-dd}.log %date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n