├── .classpath ├── .gitignore ├── .project ├── Kettle Dubbo Client Plugin.iml ├── README.md ├── build-res ├── subfloor-pkg.xml └── subfloor.xml ├── build.properties ├── build.xml ├── ivy.xml ├── ivysettings.xml ├── lib ├── commons-logging-1.1.1.jar ├── dubbo-2.5.3.jar ├── gson-2.2.4.jar ├── javassist-3.15.0-GA.jar ├── jline-0.9.94.jar ├── junit-3.8.1.jar ├── log4j-1.2.15.jar ├── netty-3.2.5.Final.jar ├── spring-2.5.6.SEC03.jar ├── zkclient-0.1.jar └── zookeeper-3.3.3.jar ├── package-ivy.xml └── src ├── DubboClient.png └── com └── gosun └── di ├── trans └── steps │ └── dubboclient │ ├── DubboClient.java │ ├── DubboClientData.java │ ├── DubboClientMeta.java │ ├── DubboProviderConst.java │ └── messages │ ├── messages_en_US.properties │ └── messages_zh_CN.properties └── ui └── trans └── steps └── dubboclient ├── DubboClientDialog.java └── utils ├── DynamicClassLoader.java └── ReflectionUtil.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /dev-lib 3 | /test-lib 4 | /dist 5 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dubbo Client Plugin 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Kettle Dubbo Client Plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 基本介绍 2 | 3 | kettle-dubboclient-plugin是基于Kettle5.3插件体系实现的Dubbo客户端插件,属于Kettle的**转换步骤插件**(StepPlugin), 通过使用这个步骤插件,可以调用由Dubbo Provider(Dubbo服务提供者)基于**dubbo协议**发布的服务。 4 | 5 | ## 插件构建 6 | 7 | 该插件追随Kettle源码的构建方式,使用 ***Ant + Ivy*** 来完成构建和解决依赖。编译构建插件仅需要执行两个Ant命令: 8 | 9 | (1) 通过命令行窗口进入项目根目录并执行如下命令来下载插件所需要的依赖jar包: 10 | 11 | ```bash 12 | ant resolve 13 | ``` 14 | 15 | (2) 通过命令行窗口进入项目根目录并执行以下命令来构建插件发布包 16 | 17 | ```bash 18 | ant dist 19 | ``` 20 | 21 | ## 集成到Kettle发布包 22 | 23 | 插件构建成功后, 在 ***/dist*** 目录下找到如下zip包: 24 | 25 | ``` 26 | kettle-dubboclient-plugin-5.3.0.4-364.zip 27 | ``` 28 | 29 | 将该zip包解压到Kettle发布包 ***/plugins*** 下,解压后的位置如下所示: 30 | 31 | ``` 32 | ${Kettle_APP_DIR}/plugins/kettle-dubboclient-plugin 33 | ``` 34 | 35 | 其中 ***${Kettle\_APP\_DIR}*** 表示你的Kettle发布包所在目录 36 | 37 | ## Dubbo Provider API的存放 38 | 39 | 需要将Dubbo服务提供者提供的服务接口相关jar放置到该插件的某个位置以便于该插件能够检索到哪些服务可以使用。在这里我们基于约定来存放Dubbo Provider API以及相关配置。对于Dubbo Provider提供的api jar包及依赖,放到 ***kettle-dubboclient-plugin*** 插件根目录下,每个Dubbo服务提供者存放的目录层次结构为: 40 | 41 | ``` 42 | ${Dubbo_Provider_DIR_NAME}/provider.properties 43 | ${Dubbo_Provider_DIR_NAME}/XXXService.jar(API jar) 44 | ${Dubbo_Provider_DIR_NAME}/lib/....(provider依赖的第三方jar) 45 | ``` 46 | 47 | 其中 ***${Dubbo\_Provider\_DIR\_NAME}*** 可以为任意自定义的目录名,表示某个特定的Dubbo服务提供者。 48 | 49 | ### 1. provider.properties 50 | 51 | 每个Dubbo Provider所在目录都必须提供一个 **provider.properties** 配置文件,配置文件里面必须提供的配置项有: 52 | 53 | (1) **provider** 54 | 55 | 用于指定特定provider名称。 56 | 57 | eg: 58 | 59 | ```bash 60 | provider=example 61 | ``` 62 | 63 | (2) **interfaces** 64 | 65 | 指定provider提供的接口,多个接口以**逗号(,)**隔开。 66 | 67 | eg: 68 | 69 | ```bash 70 | interfaces=com.example.ExampleService1,com.example.ExampleService2 71 | ``` 72 | 73 | ### 2. XXXService.jar 74 | 75 | 表示Dubbo Provider提供出来的服务接口jar包。 76 | 77 | ### 3. lib子目录 78 | 79 | lib子目录用于存放Dubbo Provider提供出来的服务接口必须依赖的第三方jar包。 80 | 81 | ## FAQ 82 | 83 | ### 1. 有新的服务提供者要加入该插件该如何操作? 84 | 85 | 对于新的服务提供者要加入该插件, 只需要按照上面所讲的配置方式存放新的服务提供者API包到插件对应位置。如果你使用的是Spoon工具, 通过重启Spoon工具就可以让Kettle在加载该插件的时候识别到新的服务提供者。 86 | 87 | ### 2. Spoon工具在哪里可以找到该插件? 88 | 89 | 因为该插件是属于转换步骤插件(StepPlugin)的, 所以在新建转换之后, 可以在 ***核心对象*** 里面找到该插件, 对应的组件名称是 ***Dubbo Client*** , 可以在 ***查询*** 分类下找到该组件。 90 | 91 | ### 3. 对于Dubbo服务接口方法调用的入参如何传递和返回值如何处理? 92 | 93 | 对于入参, 即方法参数, 如果不是基本数据类型或者其包装类(***Integer***, ***String***, ...etc), 那么要求以 ***json*** 格式来传递入参。对于返回值, 与入参采取同样的方式, 如果不是基本数据类型或者包装类, 那么会将返回值序列化成 ***json*** 格式串返回。对于基本数据类型或者包装类, 统一返回 ***String*** 字符串值。 94 | -------------------------------------------------------------------------------- /build-res/subfloor-pkg.xml: -------------------------------------------------------------------------------- 1 | 27 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 53 | 54 | 55 | 56 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 140 | 141 | 143 | 144 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | Copying files for Linux package format: ${linuxPackage.packageFormat} 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 209 | 210 | 213 | 214 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 267 | 268 | 269 | 270 | 273 | 274 | 277 | 278 | 279 | 280 | 281 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 308 | 309 | 310 | 311 | 312 | 313 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 329 | 332 | 333 | 337 | 340 | 341 | 342 | 343 | 344 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | -------------------------------------------------------------------------------- /build-res/subfloor.xml: -------------------------------------------------------------------------------- 1 | 27 | 68 | 69 | 70 | 71 | 72 | ------------------------------------------------------------------------------- 73 | subfloor.xml provides tasks needed to perform a project build. 74 | It is typically not used directly but imported by each project's build.xml 75 | file. The build.xml file can override tasks when customization is required. 76 | 77 | MAIN TARGETS 78 | ============ 79 | * clean / clean-all : 80 | remove all artifacts of the build, clean-all adds the removal 81 | of any library or jar dependencies downloaded as part of the build 82 | 83 | * resolve : 84 | download/refresh library or jar dependencies needed for the build (uses Apache IVY) 85 | 86 | * compile : 87 | run javac on the project's source 88 | 89 | * jar : 90 | creates a jar file 91 | 92 | * dist : 93 | creates all project distributables 94 | 95 | * test : 96 | runs JUnit tests from your project's test source 97 | 98 | SPECIAL TARGETS 99 | ============ 100 | * publish-local : 101 | builds a jar for your project and registers it with the local artifact repository isolated 102 | to your machine at $HOME/.ivy2/local. Further executions of the the resolve target by this 103 | or other projects will find your published jar. 104 | 105 | * ivy-clean* : 106 | this family of targets helps reset your IVY environment in the event that you are having 107 | difficulty resolving dependencies 108 | 109 | TYPICAL TARGET SEQUENCE 110 | ============ 111 | * clean-all resolve dist : 112 | a good start to build all project distributables from scratch. Note that jar dependencies 113 | will not be downloaded unless you explicitly run the resolve target. We made the resolution 114 | and retrieval completely discretionary since there are many situations in which 115 | you will not want to get or refresh dependencies, e.g. if you are offline with no Internet 116 | access. In such case, you could just run "dist" if the set of jars you already have are 117 | sufficient. 118 | 119 | 120 | 121 | 122 | 124 | 126 | 127 | 131 | 132 | 133 | 134 | 137 | 138 | 139 | 140 | 141 | 144 | 147 | 150 | 151 | 152 | 155 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 167 | 170 | 173 | 176 | 179 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 194 | 197 | 200 | 203 | 206 | 209 | 210 | 211 | 212 | 215 | 216 | 217 | 218 | 221 | 224 | 227 | 230 | 233 | 236 | 237 | 238 | 241 | 244 | 245 | 246 | 247 | 248 | 251 | 254 | 257 | 258 | 259 | 260 | 261 | 262 | 265 | 268 | 271 | 274 | 277 | 280 | 283 | 284 | 285 | 286 | 287 | 290 | 293 | 296 | 299 | 300 | 301 | 303 | 305 | 306 | 307 | 310 | 313 | 315 | 316 | 317 | 320 | 322 | 324 | 326 | 328 | 330 | 332 | 334 | 336 | 338 | 339 | 341 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 352 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 425 | 426 | 427 | 428 | 433 | 434 | 435 | 436 | 441 | 442 | 443 | 444 | 450 | 451 | 452 | 453 | 459 | 460 | 461 | 462 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 505 | 506 | 507 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 688 | 689 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 709 | 712 | 713 | 714 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 772 | 773 | 774 | 775 | 776 | 777 | 785 | 786 | 787 | 788 | 789 | 790 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 872 | 875 | 876 | 877 | 883 | 884 | 885 | 886 | 887 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 941 | 942 | 943 | 944 | 945 | 946 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1117 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1130 | 1131 | 1132 | 1133 | 1134 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1151 | 1152 | 1153 | 1154 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1195 | 1198 | 1199 | 1200 | 1205 | 1206 | 1207 | 1208 | 1213 | 1214 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1297 | 1298 | 1299 | 1300 | 1305 | 1308 | 1309 | 1310 | 1311 | 1312 | 1313 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | 1347 | 1348 | 1353 | 1354 | 1355 | 1356 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1376 | 1377 | 1378 | 1379 | 1380 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1416 | 1417 | 1424 | 1425 | 1426 | 1427 | 1428 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1443 | 1444 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1504 | 1505 | 1506 | 1507 | 1513 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1532 | 1533 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1567 | 1568 | 1569 | 1570 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1587 | 1588 | 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1600 | 1601 | 1602 | 1603 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1629 | 1630 | 1634 | 1635 | 1636 | 1637 | 1642 | 1643 | 1648 | 1649 | 1650 | 1651 | 1656 | 1659 | 1660 | 1661 | 1666 | 1667 | 1668 | 1669 | 1670 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | 1680 | 1681 | 1682 | 1683 | 1688 | 1689 | 1690 | 1691 | 1692 | 1693 | 1698 | 1699 | 1700 | 1701 | 1702 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1717 | 1718 | 1719 | 1720 | 1721 | 1722 | 1727 | 1728 | 1729 | 1730 | 1731 | 1732 | 1733 | 1734 | 1739 | 1741 | 1742 | 1743 | 1744 | 1745 | 1746 | 1747 | 1754 | 1755 | 1756 | 1757 | 1758 | 1759 | 1760 | 1761 | 1762 | 1763 | 1764 | 1768 | 1769 | 1770 | 1771 | 1772 | 1773 | 1774 | 1775 | 1776 | 1777 | 1778 | 1779 | 1780 | 1781 | 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | 1809 | 1810 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1824 | 1825 | 1826 | 1827 | 1828 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1867 | 1868 | 1871 | 1872 | 1873 | 1874 | 1876 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | 1890 | 1891 | 1892 | 1893 | 1894 | 1895 | 1896 | 1902 | 1903 | 1904 | 1905 | 1906 | 1907 | 1908 | 1909 | 1910 | 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | 1920 | 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1944 | 1945 | 1946 | 1947 | 1948 | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2022 | 2023 | 2024 | 2025 | 2026 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2109 | 2110 | 2111 | 2112 | 2113 | 2115 | 2116 | 2117 | 2122 | 2123 | 2124 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | project.revision=5.3.0.4-364 2 | ivy.artifact.group=pentaho-kettle 3 | ivy.artifact.id=kettle-dubboclient-plugin 4 | impl.vendor=Pentaho Corporation 5 | impl.title=DubboClient Plugin 6 | impl.productID=${ivy.artifact.id} 7 | dev-lib.dir=dev-lib 8 | 9 | dependency.kettle.revision=5.3.0.4-364 10 | dependency.pentaho-xul.revision=5.3.0.4-364 11 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | This build file is used to create the DubboClient core Kettle plugin 15 | and works with the subfloor.xml file. 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Staging the Kettle plugin ${ivy.artifact.id} ... 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Copying files from lib.... 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Creating the Kettle plugin zip for ${ivy.artifact.id} ... 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ivy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ivysettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /lib/commons-logging-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/commons-logging-1.1.1.jar -------------------------------------------------------------------------------- /lib/dubbo-2.5.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/dubbo-2.5.3.jar -------------------------------------------------------------------------------- /lib/gson-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/gson-2.2.4.jar -------------------------------------------------------------------------------- /lib/javassist-3.15.0-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/javassist-3.15.0-GA.jar -------------------------------------------------------------------------------- /lib/jline-0.9.94.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/jline-0.9.94.jar -------------------------------------------------------------------------------- /lib/junit-3.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/junit-3.8.1.jar -------------------------------------------------------------------------------- /lib/log4j-1.2.15.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/log4j-1.2.15.jar -------------------------------------------------------------------------------- /lib/netty-3.2.5.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/netty-3.2.5.Final.jar -------------------------------------------------------------------------------- /lib/spring-2.5.6.SEC03.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/spring-2.5.6.SEC03.jar -------------------------------------------------------------------------------- /lib/zkclient-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/zkclient-0.1.jar -------------------------------------------------------------------------------- /lib/zookeeper-3.3.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/lib/zookeeper-3.3.3.jar -------------------------------------------------------------------------------- /package-ivy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/DubboClient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZzzCrazyPig/kettle-dubboclient-plugin/cb73356b3371a77f0883f0ccbd35c8eb892e3c6d/src/DubboClient.png -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/DubboClient.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.trans.steps.dubboclient; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.pentaho.di.core.Const; 6 | import org.pentaho.di.core.exception.KettleException; 7 | import org.pentaho.di.core.exception.KettleStepException; 8 | import org.pentaho.di.core.row.RowMeta; 9 | import org.pentaho.di.i18n.BaseMessages; 10 | import org.pentaho.di.trans.Trans; 11 | import org.pentaho.di.trans.TransMeta; 12 | import org.pentaho.di.trans.step.BaseStep; 13 | import org.pentaho.di.trans.step.StepDataInterface; 14 | import org.pentaho.di.trans.step.StepInterface; 15 | import org.pentaho.di.trans.step.StepMeta; 16 | import org.pentaho.di.trans.step.StepMetaInterface; 17 | 18 | import com.alibaba.dubbo.config.ApplicationConfig; 19 | import com.alibaba.dubbo.config.ReferenceConfig; 20 | import com.alibaba.dubbo.config.RegistryConfig; 21 | import com.google.gson.Gson; 22 | import com.gosun.di.ui.trans.steps.dubboclient.utils.DynamicClassLoader; 23 | import com.gosun.di.ui.trans.steps.dubboclient.utils.ReflectionUtil; 24 | 25 | public class DubboClient extends BaseStep implements StepInterface { 26 | 27 | private static Class PKG = DubboClientMeta.class; // for i18n purposes, needed by Translator2!! 28 | 29 | private DubboClientMeta meta; 30 | private DubboClientData data; 31 | 32 | private static Gson gson = new Gson(); 33 | 34 | public DubboClient(StepMeta stepMeta, StepDataInterface stepDataInterface, 35 | int copyNr, TransMeta transMeta, Trans trans) { 36 | super(stepMeta, stepDataInterface, copyNr, transMeta, trans); 37 | } 38 | 39 | @SuppressWarnings({ "rawtypes", "unchecked" }) 40 | @Override 41 | public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) 42 | throws KettleException { 43 | meta = (DubboClientMeta) smi; 44 | data = (DubboClientData) sdi; 45 | 46 | 47 | data.outputRowMeta = new RowMeta(); 48 | meta.getFields(data.outputRowMeta, getStepname(), null, null, this, repository, metaStore); 49 | 50 | String appName = meta.getAppName(); 51 | String registryAddr = meta.getRegistryAddr(); 52 | String regProtocol = meta.getRegProtocol(); 53 | String execInterface = meta.getExecInterface(); 54 | String execMethodName = meta.getExecMethodName(); 55 | Class[] execMethodArgTypes = meta.getExecMethodArgTypes(); 56 | Class execMethodReturnType = meta.getExecMethodReturnType(); 57 | 58 | String[] argValues = meta.getArgValues(); 59 | 60 | // 检查参数 61 | if(Const.isEmpty(appName)) { 62 | throw new KettleException(BaseMessages.getString(PKG, "DubboClient.Error.AppNameEmpty")); 63 | } 64 | if(Const.isEmpty(registryAddr)) { 65 | throw new KettleException(BaseMessages.getString(PKG, "DubboClient.Error.RegistryAddrEmpty")); 66 | } 67 | if(Const.isEmpty(regProtocol)) { 68 | throw new KettleException(BaseMessages.getString(PKG, "DubboClient.Error.RegProtocolEmpty")); 69 | } 70 | if(Const.isEmpty(execInterface)) { 71 | throw new KettleException(BaseMessages.getString(PKG, "DubboClient.Error.ExecInterfaceEmpty")); 72 | } 73 | if(Const.isEmpty(execMethodName)) { 74 | throw new KettleException(BaseMessages.getString(PKG, "DubboClient.Error.ExecMethodEmpty")); 75 | } 76 | // .... 77 | 78 | // 使用dubbo client api 请求dubbo服务 79 | DynamicClassLoader dynaClassLoader = DubboClientMeta.dynaClassLoader; 80 | Class serviceClazz = null; 81 | try { 82 | serviceClazz = dynaClassLoader.loadClass(execInterface); 83 | // 配置当前应用 84 | ApplicationConfig app = new ApplicationConfig(); 85 | app.setName(appName); 86 | 87 | // 连接注册中心配置 88 | RegistryConfig registry = new RegistryConfig(); 89 | registry.setProtocol(regProtocol); // 协议,一定要配置 90 | registry.setAddress(registryAddr); 91 | 92 | // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接 93 | 94 | // 引用远程服务 95 | // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 96 | ReferenceConfig reference = new ReferenceConfig(); 97 | reference.setApplication(app); 98 | reference.setRegistry(registry); // 多个注册中心可以用setRegistries() 99 | reference.setInterface(serviceClazz); 100 | 101 | Object service = reference.get(); 102 | 103 | // 得到具体的method 104 | Method execMethod = meta.getExecMethod(); 105 | if(execMethod == null) { 106 | execMethod = ReflectionUtil.getMethod(service.getClass(), execMethodName, execMethodArgTypes); 107 | meta.setExecMethod(execMethod); 108 | } 109 | 110 | Object[] realArgValues = null; 111 | 112 | // TODO 参数类型变换 113 | // 对于复杂数据类型,传递过来的是json字符串,需要还原为实际的对象 114 | if(execMethodArgTypes != null) { 115 | realArgValues = new Object[execMethodArgTypes.length]; 116 | for(int i = 0; i < execMethodArgTypes.length; i++) { 117 | Class argType = execMethodArgTypes[i]; 118 | String className = argType.getCanonicalName(); 119 | if(!className.startsWith("java.lang")) { 120 | realArgValues[i] = gson.fromJson(argValues[i], argType); 121 | } 122 | } 123 | } 124 | 125 | // 通过反射来调用 126 | Object result = ReflectionUtil.invoke(execMethod, service, realArgValues); 127 | reference.destroy(); // 是否是必须的? 128 | // 处理返回结果 129 | processOutput(result, execMethodReturnType); 130 | // 结束状态设置 131 | setOutputDone(); 132 | 133 | 134 | } catch (Exception e) { 135 | e.printStackTrace(); 136 | throw new KettleException(e); 137 | } 138 | 139 | return false; 140 | } 141 | 142 | private void processOutput(Object result, Class methodReturnType) throws KettleStepException { 143 | // 将结果传递到下一个步骤 144 | putRow(data.outputRowMeta, new Object[]{result}); 145 | } 146 | 147 | @Override 148 | public boolean init(StepMetaInterface smi, StepDataInterface sdi) { 149 | return super.init(smi, sdi); 150 | } 151 | 152 | @Override 153 | public void dispose(StepMetaInterface smi, StepDataInterface sdi) { 154 | super.dispose(smi, sdi); 155 | } 156 | 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/DubboClientData.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.trans.steps.dubboclient; 2 | 3 | import org.pentaho.di.core.row.RowMetaInterface; 4 | import org.pentaho.di.trans.step.BaseStepData; 5 | import org.pentaho.di.trans.step.StepDataInterface; 6 | 7 | public class DubboClientData extends BaseStepData implements StepDataInterface { 8 | 9 | public RowMetaInterface outputRowMeta; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/DubboClientMeta.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.trans.steps.dubboclient; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.lang.reflect.Method; 6 | import java.net.URL; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | 12 | import org.pentaho.di.core.Const; 13 | import org.pentaho.di.core.annotations.Step; 14 | import org.pentaho.di.core.database.DatabaseMeta; 15 | import org.pentaho.di.core.exception.KettleException; 16 | import org.pentaho.di.core.exception.KettlePluginException; 17 | import org.pentaho.di.core.exception.KettleStepException; 18 | import org.pentaho.di.core.exception.KettleXMLException; 19 | import org.pentaho.di.core.row.RowMetaInterface; 20 | import org.pentaho.di.core.row.ValueMetaInterface; 21 | import org.pentaho.di.core.row.value.ValueMetaFactory; 22 | import org.pentaho.di.core.variables.VariableSpace; 23 | import org.pentaho.di.core.xml.XMLHandler; 24 | import org.pentaho.di.repository.ObjectId; 25 | import org.pentaho.di.repository.Repository; 26 | import org.pentaho.di.trans.Trans; 27 | import org.pentaho.di.trans.TransMeta; 28 | import org.pentaho.di.trans.step.BaseStepMeta; 29 | import org.pentaho.di.trans.step.StepDataInterface; 30 | import org.pentaho.di.trans.step.StepInterface; 31 | import org.pentaho.di.trans.step.StepMeta; 32 | import org.pentaho.di.trans.step.StepMetaInterface; 33 | import org.pentaho.metastore.api.IMetaStore; 34 | import org.w3c.dom.Node; 35 | 36 | import com.gosun.di.ui.trans.steps.dubboclient.utils.DynamicClassLoader; 37 | 38 | @Step( id = "DubboClient", image = "DubboClient.png", 39 | i18nPackageName = "com.gosun.di.trans.steps.dubboclient", name = "DubboClient.TransName", 40 | description = "DubboClient.TransDescription", 41 | categoryDescription = "i18n:org.pentaho.di.trans.step:BaseStep.Category.Lookup" ) 42 | public class DubboClientMeta extends BaseStepMeta implements StepMetaInterface { 43 | 44 | public static Map dubboPrividerServices; // 存放所有dubbo提供者的服务 45 | public static DynamicClassLoader dynaClassLoader; // 自定义classloader加载dubbo提供者jar 46 | 47 | private String appName; // 应用名称 48 | private String registryAddr; // 注册中心地址,形式为ip:port 49 | private String regProtocol; // 注册中心所用协议 50 | private String execProvider; // 服务提供者 51 | private String execInterface; // 服务调用接口 52 | private String execMethodName; // 服务调用方法 53 | 54 | private Method execMethod; // 调用接口的实际方法 55 | private Class[] execMethodArgTypes; // 调用方法具体参数信息 56 | private Class execMethodReturnType; // 调用方法返回值信息 57 | 58 | private String[] argValues; // 方法参数值 59 | 60 | private List allMethods; // 存放调用接口的所有可调用方法 61 | 62 | static { 63 | dubboPrividerServices = new HashMap(); 64 | dynaClassLoader = DynamicClassLoader.getDynamicClassLoader(); 65 | try { 66 | loadDubboProviderJars(); 67 | } catch (Exception e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | 72 | private static void loadDubboProviderJars() throws Exception { 73 | // TODO 这里需要解决如何存放dubbo provider目录的问题,暂时写死 74 | URL resUrl = DubboClientMeta.class.getClassLoader().getResource("./plugins/kettle-dubboclient-plugin/dubboProvider"); 75 | 76 | String basePath = resUrl.getFile(); 77 | 78 | File rootFile = new File(basePath); 79 | if(rootFile.exists() && rootFile.isDirectory()) { 80 | File[] subFiles = rootFile.listFiles(); 81 | for(File subFile : subFiles) { 82 | if(subFile.isDirectory()) { 83 | loadDubboProviderJar(subFile); 84 | } 85 | } 86 | } 87 | 88 | } 89 | 90 | // 加载dubbo提供者jar 91 | private static void loadDubboProviderJar(File jarDir) throws Exception { 92 | Properties props = new Properties(); 93 | File mainfestFile = new File(jarDir, DubboProviderConst.PROVIDER_DEFITION_FILE_NAME); 94 | if(mainfestFile.exists() && mainfestFile.isFile()) { 95 | FileInputStream fin = new FileInputStream(mainfestFile); 96 | props.load(fin); 97 | fin.close(); 98 | String providerName = props.getProperty(DubboProviderConst.PROP_PROVIDER_NAME); 99 | String interfaces = props.getProperty(DubboProviderConst.PROP_PROVIDER_INTERFACES); 100 | dynaClassLoader.loadJarInDir(jarDir.getPath()); 101 | String libPath = jarDir.getPath() + DubboProviderConst.PROVIDER_LIB_PATH; 102 | dynaClassLoader.loadJarInDir(libPath); 103 | String[] serviceClassNames = interfaces.split(","); 104 | dubboPrividerServices.put(providerName, serviceClassNames); 105 | } 106 | } 107 | 108 | @Override 109 | public String getDialogClassName() { 110 | // 在这里可以自定义step dialog的全限定类名 111 | return super.getDialogClassName(); 112 | } 113 | 114 | @Override 115 | public void setDefault() { 116 | // do something ??? 117 | } 118 | 119 | @Override 120 | public StepInterface getStep(StepMeta stepMeta, 121 | StepDataInterface stepDataInterface, int copyNr, 122 | TransMeta transMeta, Trans trans) { 123 | return new DubboClient(stepMeta, stepDataInterface, copyNr, transMeta, trans); 124 | } 125 | 126 | @Override 127 | public StepDataInterface getStepData() { 128 | return new DubboClientData(); 129 | } 130 | 131 | @Override 132 | public void getFields( RowMetaInterface r, String name, RowMetaInterface[] info, StepMeta nextStep, 133 | VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException { 134 | 135 | // 参考webservice组件 136 | // // Input rows and output rows are different in the webservice step 137 | // // 138 | // if ( !isPassingInputData() ) { 139 | // r.clear(); 140 | // } 141 | // 142 | // // Add the output fields... 143 | // // 144 | // for ( WebServiceField field : getFieldsOut() ) { 145 | // int valueType = field.getType(); 146 | // 147 | // // If the type is unrecognized we give back the XML as a String... 148 | // // 149 | // if ( field.getType() == ValueMetaInterface.TYPE_NONE ) { 150 | // valueType = ValueMetaInterface.TYPE_STRING; 151 | // } 152 | // 153 | // try { 154 | // ValueMetaInterface vValue = ValueMetaFactory.createValueMeta( field.getName(), valueType ); 155 | // vValue.setOrigin( name ); 156 | // r.addValueMeta( vValue ); 157 | // } catch ( Exception e ) { 158 | // throw new KettleStepException( e ); 159 | // } 160 | // } 161 | 162 | // 设置dubbo调用返回值 163 | ValueMetaInterface vValue = null; 164 | try { 165 | vValue = ValueMetaFactory.createValueMeta("return", ValueMetaInterface.TYPE_STRING); 166 | r.addValueMeta(vValue); 167 | } catch (KettlePluginException e) { 168 | throw new KettleStepException( e ); 169 | } 170 | 171 | } 172 | 173 | 174 | // 返回DubboClientMeta信息,以xml格式返回 175 | @Override 176 | public String getXML() throws KettleException { 177 | StringBuffer retval = new StringBuffer(); 178 | 179 | // 保存应用配置 180 | // 181 | retval.append( " " + XMLHandler.addTagValue( "dcAppName", getAppName() ) ); 182 | 183 | // 保存注册中心配置 184 | // 185 | retval.append( " " + XMLHandler.addTagValue( "dcRegistryAddr", getRegistryAddr() ) ); 186 | retval.append( " " + XMLHandler.addTagValue( "dcRegProtocol", getRegProtocol() ) ); 187 | 188 | 189 | // 保存提供者配置 190 | retval.append( " " + XMLHandler.addTagValue( "dcExecProvider", getExecProvider() ) ); 191 | retval.append( " " + XMLHandler.addTagValue( "dcExecInterface", getExecInterface() ) ); 192 | retval.append( " " + XMLHandler.addTagValue( "dcExecMethod", getExecMethodName() ) ); 193 | 194 | // // 保存调用方法参数信息 195 | // // 196 | retval.append( " " + Const.CR ); 197 | for ( int i = 0; i < execMethodArgTypes.length; i++ ) { 198 | Class argType = execMethodArgTypes[i]; 199 | String argValue = null; 200 | if(argValues.length >= i) { 201 | argValue = argValues[i]; 202 | } 203 | retval.append( " " + Const.CR ); 204 | retval.append( " " + XMLHandler.addTagValue( "argName", "arg" + i ) ); 205 | retval.append( " " + XMLHandler.addTagValue( "argType", argType.getCanonicalName() ) ); 206 | retval.append( " " + XMLHandler.addTagValue( "argValue", argValue ) ); 207 | retval.append( " " + Const.CR ); 208 | } 209 | retval.append( " " + Const.CR ); 210 | 211 | // // 保存调用方法返回信息 212 | // // 213 | retval.append( " " + Const.CR ); 214 | retval.append( " " + XMLHandler.addTagValue( "returnType", execMethodReturnType.getCanonicalName() ) ); 215 | retval.append( " " + Const.CR ); 216 | 217 | return retval.toString(); 218 | } 219 | 220 | // 从资源库中获取DubboClientMeta信息 221 | @Override 222 | public void readRep(Repository rep, IMetaStore metaStore, ObjectId id_step, 223 | List databases) throws KettleException { 224 | 225 | // 应用配置 226 | setAppName(rep.getStepAttributeString(id_step, "dcAppName")); 227 | 228 | // 注册中心配置 229 | setRegistryAddr(rep.getStepAttributeString(id_step, "dcRegistryAddr")); 230 | setRegProtocol(rep.getStepAttributeString(id_step, "dcRegProtocol")); 231 | 232 | // 提供者配置 233 | setExecProvider(rep.getStepAttributeString(id_step, "dcExecProvider")); 234 | setExecInterface(rep.getStepAttributeString(id_step, "dcExecInterface")); 235 | setExecMethodName(rep.getStepAttributeString(id_step, "dcExecMethod")); 236 | 237 | // 调用方法参数配置 238 | int nr = rep.countNrStepAttributes(id_step, "arg_type"); 239 | Class[] methodArgTypes = new Class[nr]; 240 | String[] argValues = new String[nr]; 241 | try { 242 | for(int i = 0; i < nr; i++) { 243 | methodArgTypes[i] = dynaClassLoader.loadClass(rep.getStepAttributeString(id_step, i, "arg_type")); 244 | argValues[i] = rep.getStepAttributeString(id_step, i, "arg_value"); 245 | } 246 | setExecMethodArgTypes(methodArgTypes); 247 | setArgValues(argValues); 248 | } catch(ClassNotFoundException e) { 249 | throw new KettleException(e); 250 | } 251 | 252 | 253 | // 调用方法返回值配置 254 | Class methodReturnType = null; 255 | try { 256 | methodReturnType = dynaClassLoader.loadClass(rep.getStepAttributeString(id_step, "return_type")); 257 | setExecMethodReturnType(methodReturnType); 258 | } catch(ClassNotFoundException e) { 259 | throw new KettleException(e); 260 | } 261 | 262 | } 263 | 264 | // 从xml节点中加载DubboClientMeta信息 265 | @Override 266 | public void loadXML(Node stepnode, List databases, 267 | IMetaStore metaStore) throws KettleXMLException { 268 | 269 | // 应用配置 270 | setAppName(XMLHandler.getTagValue(stepnode, "dcAppName")); 271 | 272 | // 注册中心配置 273 | setRegistryAddr(XMLHandler.getTagValue(stepnode, "dcRegistryAddr")); 274 | setRegProtocol(XMLHandler.getTagValue(stepnode, "dcRegProtocol")); 275 | 276 | // 提供者配置 277 | setExecProvider(XMLHandler.getTagValue(stepnode, "dcExecProvider")); 278 | setExecInterface(XMLHandler.getTagValue(stepnode, "dcExecInterface")); 279 | setExecMethodName(XMLHandler.getTagValue(stepnode, "dcExecMethod")); 280 | 281 | // 调用方法参数配置 282 | Node args = XMLHandler.getSubNode(stepnode, "args"); 283 | int nrArgs = XMLHandler.countNodes(args, "arg"); 284 | 285 | Class[] methodArgTypes = new Class[nrArgs]; 286 | String[] argValues = new String[nrArgs]; 287 | 288 | try { 289 | for(int i = 0; i < nrArgs; i++) { 290 | Node arg = XMLHandler.getSubNodeByNr(args, "arg", i); 291 | methodArgTypes[i] = dynaClassLoader.loadClass(XMLHandler.getTagValue(arg, "argType")); 292 | argValues[i] = XMLHandler.getTagValue(arg, "argValue"); 293 | } 294 | setExecMethodArgTypes(methodArgTypes); 295 | setArgValues(argValues); 296 | } catch(ClassNotFoundException e) { 297 | throw new KettleXMLException(e); 298 | } 299 | 300 | // 调用方法返回值配置 301 | Node ret = XMLHandler.getSubNode(stepnode, "return"); 302 | try { 303 | Class methodReturnType = dynaClassLoader.loadClass(XMLHandler.getTagValue(ret, "returnType")); 304 | setExecMethodReturnType(methodReturnType); 305 | } catch (ClassNotFoundException e) { 306 | throw new KettleXMLException(e); 307 | } 308 | } 309 | 310 | // 保存DubboClientMeta信息到资源库中 311 | @Override 312 | public void saveRep(Repository rep, IMetaStore metaStore, 313 | ObjectId id_transformation, ObjectId id_step) 314 | throws KettleException { 315 | 316 | // 应用配置 317 | rep.saveStepAttribute(id_transformation, id_step, "dcAppName", getAppName()); 318 | 319 | // 注册中心配置 320 | rep.saveStepAttribute(id_transformation, id_step, "dcRegistryAddr", getRegistryAddr()); 321 | rep.saveStepAttribute(id_transformation, id_step, "dcRegProtocol", getRegProtocol()); 322 | 323 | // 提供者配置 324 | rep.saveStepAttribute(id_transformation, id_step, "dcExecProvider", getExecProvider()); 325 | rep.saveStepAttribute(id_transformation, id_step, "dcExecInterface", getExecInterface()); 326 | rep.saveStepAttribute(id_transformation, id_step, "dcExecMethod", getExecMethodName()); 327 | 328 | 329 | // 调用方法参数配置 330 | for(int i = 0; i < execMethodArgTypes.length; i++) { 331 | Class argType = execMethodArgTypes[i]; 332 | String argValue = argValues[i]; 333 | rep.saveStepAttribute(id_transformation, id_step, i, "arg_name", "arg" + i); 334 | rep.saveStepAttribute(id_transformation, id_step, i, "arg_type", argType.getCanonicalName()); 335 | rep.saveStepAttribute(id_transformation, id_step, i, "arg_value", argValue); 336 | } 337 | 338 | // 调用方法返回值配置 339 | rep.saveStepAttribute(id_transformation, id_step, "return_type", execMethodReturnType.getCanonicalName()); 340 | 341 | } 342 | 343 | public String getAppName() { 344 | return appName; 345 | } 346 | 347 | public void setAppName(String appName) { 348 | this.appName = appName; 349 | } 350 | 351 | public String getRegistryAddr() { 352 | return registryAddr; 353 | } 354 | 355 | public void setRegistryAddr(String registryAddr) { 356 | this.registryAddr = registryAddr; 357 | } 358 | 359 | public String getRegProtocol() { 360 | return regProtocol; 361 | } 362 | 363 | public void setRegProtocol(String regProtocol) { 364 | this.regProtocol = regProtocol; 365 | } 366 | 367 | public String getExecProvider() { 368 | return execProvider; 369 | } 370 | 371 | public void setExecProvider(String execProvider) { 372 | this.execProvider = execProvider; 373 | } 374 | 375 | public String getExecInterface() { 376 | return execInterface; 377 | } 378 | 379 | public void setExecInterface(String execInterface) { 380 | this.execInterface = execInterface; 381 | } 382 | 383 | public String getExecMethodName() { 384 | return execMethodName; 385 | } 386 | 387 | public void setExecMethodName(String execMethodName) { 388 | this.execMethodName = execMethodName; 389 | } 390 | 391 | public List getAllMethods() { 392 | return allMethods; 393 | } 394 | 395 | public void setAllMethods(List allMethods) { 396 | this.allMethods = allMethods; 397 | } 398 | 399 | public Class[] getExecMethodArgTypes() { 400 | return execMethodArgTypes; 401 | } 402 | 403 | public void setExecMethodArgTypes(Class[] execMethodArgTypes) { 404 | this.execMethodArgTypes = execMethodArgTypes; 405 | } 406 | 407 | public Class getExecMethodReturnType() { 408 | return execMethodReturnType; 409 | } 410 | 411 | public void setExecMethodReturnType(Class execMethodReturnType) { 412 | this.execMethodReturnType = execMethodReturnType; 413 | } 414 | 415 | public Method getExecMethod() { 416 | return execMethod; 417 | } 418 | 419 | public void setExecMethod(Method execMethod) { 420 | this.execMethod = execMethod; 421 | } 422 | 423 | public String[] getArgValues() { 424 | return argValues; 425 | } 426 | 427 | public void setArgValues(String[] argValues) { 428 | this.argValues = argValues; 429 | } 430 | 431 | 432 | } 433 | -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/DubboProviderConst.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.trans.steps.dubboclient; 2 | 3 | public interface DubboProviderConst { 4 | 5 | public static final String PROVIDER_DEFITION_FILE_NAME = "provider.properties"; 6 | 7 | public static final String PROVIDER_LIB_PATH = "/lib"; 8 | 9 | public static final String PROP_PROVIDER_NAME = "provider"; 10 | public static final String PROP_PROVIDER_INTERFACES = "interfaces"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/messages/messages_en_US.properties: -------------------------------------------------------------------------------- 1 | DubboClient.TransName=Dubbo Client 2 | DubboClient.TransDescription=execute dubbo Provider Service 3 | 4 | DubboClientDialog.DialogTitle=Dubbo Client 5 | DubboClientDialog.MainTab.TabTitle=Main Config 6 | DubboClientDialog.ApplicationConfig.Label=App Config 7 | DubboClientDialog.AppName.Label=App Name 8 | DubboClientDialog.AppName.Tooltip=Please input app name 9 | DubboClientDialog.RegistryConfig.Label=Registry Config 10 | DubboClientDialog.RegistryAddr.Label=Registry Address 11 | DubboClientDialog.RegistryAddr.Tooltip=Please input dubbo registry address,format is ip:port 12 | DubboClientDialog.RegProtocol.Label=Registry Protocol 13 | DubboClientDialog.RegProtocol.Tooltip=Choose registry protocol 14 | DubboClientDialog.ExecuteConfig.Label=Execution Config 15 | DubboClientDialog.ExecProvider.Label=Service Provider 16 | DubboClientDialog.ExecProvider.Tooltip=Choose service provider 17 | DubboClientDialog.ExecInterface.Label=Execution Interface 18 | DubboClientDialog.ExecInterface.Tooltip=Choose execution interface 19 | DubboClientDialog.ExecMethod.Label=Execution Method 20 | DubboClientDialog.ExecMethod.Tooltip=Please choose execution method 21 | 22 | 23 | DubboClient.Error.AppNameEmpty=AppName must not be empty 24 | DubboClient.Error.RegistryAddrEmpty=RegistryAddr must not be empty 25 | DubboClient.Error.RegProtocolEmpty=RegProtocol must not be empty 26 | DubboClient.Error.ExecInterfaceEmpty=ExecInterface must not be empty 27 | DubboClient.Error.ExecMethodEmpty=ExecMethod must not be empty -------------------------------------------------------------------------------- /src/com/gosun/di/trans/steps/dubboclient/messages/messages_zh_CN.properties: -------------------------------------------------------------------------------- 1 | DubboClient.TransName=Dubbo Client 2 | DubboClient.TransDescription=dubbo\u5BA2\u6237\u7AEF\u8C03\u7528 3 | 4 | DubboClientDialog.DialogTitle=Dubbo\u5BA2\u6237\u7AEF 5 | DubboClientDialog.MainTab.TabTitle=\u4E3B\u914D\u7F6E 6 | DubboClientDialog.ApplicationConfig.Label=\u5E94\u7528\u914D\u7F6E 7 | DubboClientDialog.AppName.Label=\u5E94\u7528\u540D\u79F0 8 | DubboClientDialog.AppName.Tooltip=\u8BF7\u8F93\u5165dubbo\u5BA2\u6237\u7AEF\u5E94\u7528\u540D\u79F0 9 | DubboClientDialog.RegistryConfig.Label=\u6CE8\u518C\u4E2D\u5FC3\u914D\u7F6E 10 | DubboClientDialog.RegistryAddr.Label=\u6CE8\u518C\u4E2D\u5FC3\u5730\u5740 11 | DubboClientDialog.RegistryAddr.Tooltip=\u8BF7\u8F93\u5165\u6CE8\u518C\u4E2D\u5FC3\u5730\u5740,\u683C\u5F0F\u4E3A[ip:port] 12 | DubboClientDialog.RegProtocol.Label=\u6CE8\u518C\u4E2D\u5FC3\u534F\u8BAE 13 | DubboClientDialog.RegProtocol.Tooltip=\u9009\u62E9\u6CE8\u518C\u4E2D\u5FC3\u534F\u8BAE 14 | DubboClientDialog.ExecuteConfig.Label=\u8C03\u7528 15 | DubboClientDialog.ExecProvider.Label=\u670D\u52A1\u63D0\u4F9B\u65B9 16 | DubboClientDialog.ExecProvider.Tooltip=\u9009\u62E9\u670D\u52A1\u63D0\u4F9B\u65B9 17 | DubboClientDialog.ExecInterface.Label=\u8C03\u7528\u63A5\u53E3 18 | DubboClientDialog.ExecInterface.Tooltip=\u9009\u62E9\u8C03\u7528\u63A5\u53E3 19 | DubboClientDialog.ExecMethod.Label=\u8C03\u7528\u65B9\u6CD5 20 | DubboClientDialog.ExecMethod.Tooltip=\u8BF7\u9009\u62E9\u8C03\u7528\u65B9\u6CD5 21 | 22 | DubboClient.Error.AppNameEmpty=\u5E94\u7528\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A 23 | DubboClient.Error.RegistryAddrEmpty=\u6CE8\u518C\u4E2D\u5FC3\u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A 24 | DubboClient.Error.RegProtocolEmpty=\u6CE8\u518C\u4E2D\u5FC3\u534F\u8BAE\u4E0D\u80FD\u4E3A\u7A7A 25 | DubboClient.Error.ExecInterfaceEmpty=\u8C03\u7528\u63A5\u53E3\u4E0D\u80FD\u4E3A\u7A7A 26 | DubboClient.Error.ExecMethodEmpty=\u8C03\u7528\u65B9\u6CD5\u4E0D\u80FD\u4E3A\u7A7A -------------------------------------------------------------------------------- /src/com/gosun/di/ui/trans/steps/dubboclient/DubboClientDialog.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.ui.trans.steps.dubboclient; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | import java.util.TreeSet; 8 | 9 | import org.eclipse.swt.SWT; 10 | import org.eclipse.swt.custom.CCombo; 11 | import org.eclipse.swt.custom.CTabFolder; 12 | import org.eclipse.swt.custom.CTabItem; 13 | import org.eclipse.swt.events.ModifyEvent; 14 | import org.eclipse.swt.events.ModifyListener; 15 | import org.eclipse.swt.events.SelectionAdapter; 16 | import org.eclipse.swt.events.SelectionEvent; 17 | import org.eclipse.swt.events.ShellAdapter; 18 | import org.eclipse.swt.events.ShellEvent; 19 | import org.eclipse.swt.layout.FormAttachment; 20 | import org.eclipse.swt.layout.FormData; 21 | import org.eclipse.swt.layout.FormLayout; 22 | import org.eclipse.swt.widgets.Button; 23 | import org.eclipse.swt.widgets.Composite; 24 | import org.eclipse.swt.widgets.Display; 25 | import org.eclipse.swt.widgets.Group; 26 | import org.eclipse.swt.widgets.Label; 27 | import org.eclipse.swt.widgets.Shell; 28 | import org.eclipse.swt.widgets.TableItem; 29 | import org.eclipse.swt.widgets.Text; 30 | import org.pentaho.di.core.Const; 31 | import org.pentaho.di.core.Props; 32 | import org.pentaho.di.i18n.BaseMessages; 33 | import org.pentaho.di.trans.TransMeta; 34 | import org.pentaho.di.trans.step.BaseStepMeta; 35 | import org.pentaho.di.trans.step.StepDialogInterface; 36 | import org.pentaho.di.ui.core.widget.ColumnInfo; 37 | import org.pentaho.di.ui.core.widget.TableView; 38 | import org.pentaho.di.ui.core.widget.TextVar; 39 | import org.pentaho.di.ui.trans.step.BaseStepDialog; 40 | 41 | import com.gosun.di.trans.steps.dubboclient.DubboClientMeta; 42 | import com.gosun.di.ui.trans.steps.dubboclient.utils.ReflectionUtil; 43 | 44 | public class DubboClientDialog extends BaseStepDialog implements StepDialogInterface { 45 | 46 | private static Class PKG = DubboClientMeta.class; // for i18n purposes, needed by Translator2!! 47 | 48 | private DubboClientMeta meta; 49 | 50 | private CTabFolder wTabFolder; 51 | 52 | private CTabItem tabItemDubboClient; 53 | private CTabItem tabItemArgs; 54 | 55 | private Label wlAppName; 56 | private TextVar wAppName; 57 | 58 | private Label wlRegistryAddr; 59 | private TextVar wRegistryAddr; 60 | 61 | private Label wlRegProtocol; 62 | private CCombo wRegProtocol; 63 | 64 | private Label wlExecProvider; 65 | private CCombo wExecProvider; 66 | 67 | private Label wlExecInterface; 68 | private CCombo wExecInterface; 69 | 70 | private Label wlExecMethod; 71 | private CCombo wExecMethod; 72 | 73 | private TableView argsTableView; 74 | 75 | private ModifyListener lsMod = new ModifyListener() { 76 | public void modifyText( ModifyEvent e ) { 77 | meta.setChanged(); 78 | } 79 | }; 80 | 81 | public DubboClientDialog(Shell parent, Object in, 82 | TransMeta transMeta, String stepname) { 83 | super(parent, (BaseStepMeta) in, transMeta, stepname); 84 | this.meta = (DubboClientMeta) in; 85 | } 86 | 87 | @Override 88 | public String open() { 89 | Shell parent = getParent(); 90 | Display display = parent.getDisplay(); 91 | 92 | shell = new Shell( parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN ); 93 | props.setLook( shell ); 94 | setShellImage( shell, meta ); // 设置dialog icon图标 95 | 96 | changed = meta.hasChanged(); 97 | 98 | // 设置界面主布局 99 | FormLayout formLayout = new FormLayout(); 100 | formLayout.marginWidth = Const.FORM_MARGIN; 101 | formLayout.marginHeight = Const.FORM_MARGIN; 102 | 103 | shell.setLayout( formLayout ); 104 | shell.setText( BaseMessages.getString( PKG, "DubboClientDialog.DialogTitle" ) ); 105 | 106 | int middle = props.getMiddlePct(); 107 | int margin = Const.MARGIN; 108 | 109 | // 步骤名称设置 110 | wlStepname = new Label( shell, SWT.RIGHT ); 111 | wlStepname.setText( BaseMessages.getString( PKG, "System.Label.StepName" ) ); 112 | props.setLook( wlStepname ); 113 | fdlStepname = new FormData(); 114 | fdlStepname.left = new FormAttachment( 0, 0 ); 115 | fdlStepname.top = new FormAttachment( 0, margin ); 116 | fdlStepname.right = new FormAttachment( middle, -margin ); 117 | wlStepname.setLayoutData( fdlStepname ); 118 | wStepname = new Text( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 119 | wStepname.setText( stepname ); 120 | props.setLook( wStepname ); 121 | wStepname.addModifyListener( lsMod ); 122 | fdStepname = new FormData(); 123 | fdStepname.left = new FormAttachment( middle, 0 ); 124 | fdStepname.top = new FormAttachment( 0, margin ); 125 | fdStepname.right = new FormAttachment( 100, 0 ); 126 | wStepname.setLayoutData( fdStepname ); 127 | 128 | // 配置tab 129 | wTabFolder = new CTabFolder( shell, SWT.BORDER ); 130 | props.setLook( wTabFolder, Props.WIDGET_STYLE_TAB ); 131 | 132 | tabItemDubboClient = new CTabItem( wTabFolder, SWT.NONE ); 133 | tabItemDubboClient.setText( BaseMessages.getString( PKG, "DubboClientDialog.MainTab.TabTitle" ) ); 134 | Composite compositeTabDubboClient = new Composite( wTabFolder, SWT.NONE ); 135 | props.setLook( compositeTabDubboClient ); 136 | 137 | FormLayout fileLayout = new FormLayout(); 138 | fileLayout.marginWidth = 3; 139 | fileLayout.marginHeight = 3; 140 | compositeTabDubboClient.setLayout( fileLayout ); 141 | 142 | // 新建field set(应用配置) 143 | 144 | Group gApp = new Group( compositeTabDubboClient, SWT.SHADOW_ETCHED_IN ); 145 | gApp.setText( BaseMessages.getString( PKG, "DubboClientDialog.ApplicationConfig.Label" ) ); 146 | FormLayout appLayout = new FormLayout(); 147 | appLayout.marginWidth = 3; 148 | appLayout.marginHeight = 3; 149 | gApp.setLayout( appLayout ); 150 | props.setLook( gApp ); 151 | 152 | wlAppName = new Label(gApp, SWT.RIGHT); 153 | wlAppName.setText( BaseMessages.getString( PKG, "DubboClientDialog.AppName.Label" ) ); 154 | props.setLook( wlAppName ); 155 | FormData fdlAppName = new FormData(); 156 | fdlAppName.top = new FormAttachment( 0, margin ); 157 | fdlAppName.left = new FormAttachment( 0, 0 ); 158 | fdlAppName.right = new FormAttachment( middle, -margin ); 159 | wlAppName.setLayoutData( fdlAppName ); 160 | wAppName = new TextVar( transMeta, gApp, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 161 | wAppName.addModifyListener( lsMod ); 162 | wAppName.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.AppName.Tooltip" ) ); 163 | props.setLook( wAppName ); 164 | FormData fdAppName = new FormData(); 165 | fdAppName.top = new FormAttachment( 0, margin ); 166 | fdAppName.left = new FormAttachment( middle, 0 ); 167 | fdAppName.right = new FormAttachment( 100, 0 ); 168 | wAppName.setLayoutData( fdAppName ); 169 | 170 | FormData fdApp = new FormData(); 171 | fdApp.left = new FormAttachment( 0, 0 ); 172 | fdApp.right = new FormAttachment( 100, 0 ); 173 | fdApp.top = new FormAttachment( 0, margin ); 174 | gApp.setLayoutData( fdApp ); 175 | 176 | 177 | // 新建field set(注册中心配置) 178 | Group gRegistry = new Group( compositeTabDubboClient, SWT.SHADOW_ETCHED_IN ); 179 | gRegistry.setText( BaseMessages.getString( PKG, "DubboClientDialog.RegistryConfig.Label" ) ); 180 | FormLayout registryLayout = new FormLayout(); 181 | registryLayout.marginWidth = 3; 182 | registryLayout.marginHeight = 3; 183 | gRegistry.setLayout( registryLayout ); 184 | props.setLook( gRegistry ); 185 | 186 | // 注册中心地址 187 | wlRegistryAddr = new Label(gRegistry, SWT.RIGHT); 188 | wlRegistryAddr.setText( BaseMessages.getString( PKG, "DubboClientDialog.RegistryAddr.Label" ) ); 189 | props.setLook( wlRegistryAddr ); 190 | FormData fdlRegistryAddr = new FormData(); 191 | fdlRegistryAddr.top = new FormAttachment( 0, margin ); 192 | fdlRegistryAddr.left = new FormAttachment( 0, 0 ); 193 | fdlRegistryAddr.right = new FormAttachment( middle, -margin ); 194 | wlRegistryAddr.setLayoutData( fdlRegistryAddr ); 195 | wRegistryAddr = new TextVar( transMeta, gRegistry, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 196 | wRegistryAddr.addModifyListener( lsMod ); 197 | wRegistryAddr.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.RegistryAddr.Tooltip" ) ); 198 | props.setLook( wRegistryAddr ); 199 | FormData fdRegistryAddr = new FormData(); 200 | fdRegistryAddr.top = new FormAttachment( 0, margin ); 201 | fdRegistryAddr.left = new FormAttachment( middle, 0 ); 202 | fdRegistryAddr.right = new FormAttachment( 100, 0 ); 203 | wRegistryAddr.setLayoutData( fdRegistryAddr ); 204 | 205 | // 注册中心所用协议 206 | wlRegProtocol = new Label(gRegistry, SWT.RIGHT); 207 | wlRegProtocol.setText( BaseMessages.getString( PKG, "DubboClientDialog.RegProtocol.Label" ) ); 208 | props.setLook( wlRegProtocol ); 209 | FormData fdlRegProtocol = new FormData(); 210 | fdlRegProtocol.top = new FormAttachment( wRegistryAddr, margin ); 211 | fdlRegProtocol.left = new FormAttachment( 0, 0 ); 212 | fdlRegProtocol.right = new FormAttachment( middle, -margin ); 213 | wlRegProtocol.setLayoutData( fdlRegProtocol ); 214 | wRegProtocol = new CCombo( gRegistry, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 215 | wRegProtocol.addModifyListener( lsMod ); 216 | wRegProtocol.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.RegProtocol.Tooltip" ) ); 217 | props.setLook( wRegProtocol ); 218 | FormData fdRegProcotol = new FormData(); 219 | fdRegProcotol.top = new FormAttachment( wRegistryAddr, margin ); 220 | fdRegProcotol.left = new FormAttachment( middle, 0 ); 221 | fdRegProcotol.right = new FormAttachment( 100, 0 ); 222 | wRegProtocol.setLayoutData( fdRegProcotol ); 223 | 224 | wRegProtocol.setItems(new String[]{ 225 | "zookeeper" 226 | }); 227 | 228 | FormData fdRegistry = new FormData(); 229 | fdRegistry.left = new FormAttachment( 0, 0 ); 230 | fdRegistry.right = new FormAttachment( 100, 0 ); 231 | fdRegistry.top = new FormAttachment( gApp, margin ); 232 | gRegistry.setLayoutData( fdRegistry ); 233 | 234 | 235 | // 新建field set(调用) 236 | Group gExecute = new Group( compositeTabDubboClient, SWT.SHADOW_ETCHED_IN ); 237 | gExecute.setText( BaseMessages.getString( PKG, "DubboClientDialog.ExecuteConfig.Label" ) ); 238 | FormLayout execLayout = new FormLayout(); 239 | execLayout.marginWidth = 3; 240 | execLayout.marginHeight = 3; 241 | gExecute.setLayout( execLayout ); 242 | props.setLook( gExecute ); 243 | 244 | // 提供者 245 | wlExecProvider = new Label(gExecute, SWT.RIGHT); 246 | wlExecProvider.setText(BaseMessages.getString(PKG, "DubboClientDialog.ExecProvider.Label")); 247 | props.setLook(wlExecProvider); 248 | FormData fdlExecProvider = new FormData(); 249 | fdlExecProvider.top = new FormAttachment( 0, margin ); 250 | fdlExecProvider.left = new FormAttachment( 0, 0 ); 251 | fdlExecProvider.right = new FormAttachment( middle, -margin ); 252 | wlExecProvider.setLayoutData(fdlExecProvider); 253 | wExecProvider = new CCombo(gExecute, SWT.SINGLE | SWT.LEFT | SWT.BORDER); 254 | wExecProvider.addModifyListener(lsMod); 255 | wExecProvider.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.ExecProvider.Tooltip" ) ); 256 | props.setLook( wExecProvider ); 257 | FormData fdExecProvider = new FormData(); 258 | fdExecProvider.top = new FormAttachment( 0, margin ); 259 | fdExecProvider.left = new FormAttachment( middle, 0 ); 260 | fdExecProvider.right = new FormAttachment( 100, 0 ); 261 | wExecProvider.setLayoutData( fdExecProvider ); 262 | 263 | 264 | wExecProvider.addSelectionListener(new SelectionAdapter() { 265 | 266 | @Override 267 | public void widgetSelected(SelectionEvent e) { 268 | onProviderSelected(e); 269 | } 270 | 271 | }); 272 | 273 | 274 | 275 | // 调用接口 276 | wlExecInterface = new Label(gExecute, SWT.RIGHT); 277 | wlExecInterface.setText( BaseMessages.getString( PKG, "DubboClientDialog.ExecInterface.Label" ) ); 278 | props.setLook( wlExecInterface ); 279 | FormData fdlExecInterface = new FormData(); 280 | fdlExecInterface.top = new FormAttachment( wExecProvider, margin ); 281 | fdlExecInterface.left = new FormAttachment( 0, 0 ); 282 | fdlExecInterface.right = new FormAttachment( middle, -margin ); 283 | wlExecInterface.setLayoutData( fdlExecInterface ); 284 | wExecInterface = new CCombo( gExecute, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 285 | wExecInterface.addModifyListener( lsMod ); 286 | wExecInterface.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.ExecInterface.Tooltip" ) ); 287 | props.setLook( wExecInterface ); 288 | FormData fdExecInterface = new FormData(); 289 | fdExecInterface.top = new FormAttachment( wExecProvider, margin ); 290 | fdExecInterface.left = new FormAttachment( middle, 0 ); 291 | fdExecInterface.right = new FormAttachment( 100, 0 ); 292 | wExecInterface.setLayoutData( fdExecInterface ); 293 | 294 | wExecInterface.addSelectionListener(new SelectionAdapter() { 295 | 296 | @Override 297 | public void widgetSelected(SelectionEvent e) { 298 | try { 299 | onInterfaceSelected(e); 300 | } catch (Exception e1) { 301 | e1.printStackTrace(); 302 | } 303 | } 304 | 305 | }); 306 | 307 | 308 | // 调用方法 309 | wlExecMethod = new Label(gExecute, SWT.RIGHT); 310 | wlExecMethod.setText( BaseMessages.getString( PKG, "DubboClientDialog.ExecMethod.Label" ) ); 311 | props.setLook( wlExecMethod ); 312 | FormData fdlExecMethod = new FormData(); 313 | fdlExecMethod.top = new FormAttachment( wExecInterface, margin ); 314 | fdlExecMethod.left = new FormAttachment( 0, 0 ); 315 | fdlExecMethod.right = new FormAttachment( middle, -margin ); 316 | wlExecMethod.setLayoutData( fdlExecMethod ); 317 | wExecMethod = new CCombo( gExecute, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); 318 | wExecMethod.addModifyListener( lsMod ); 319 | wExecMethod.setToolTipText( BaseMessages.getString( PKG, "DubboClientDialog.ExecMethod.Tooltip" ) ); 320 | props.setLook( wExecMethod ); 321 | FormData fdExecMethod = new FormData(); 322 | fdExecMethod.top = new FormAttachment( wExecInterface, margin ); 323 | fdExecMethod.left = new FormAttachment( middle, 0 ); 324 | fdExecMethod.right = new FormAttachment( 100, 0 ); 325 | wExecMethod.setLayoutData( fdExecMethod ); 326 | 327 | wExecMethod.addSelectionListener(new SelectionAdapter() { 328 | 329 | @Override 330 | public void widgetSelected(SelectionEvent e) { 331 | onMethodSelected(e); 332 | } 333 | 334 | }); 335 | 336 | FormData fdExecute = new FormData(); 337 | fdExecute.left = new FormAttachment( 0, 0 ); 338 | fdExecute.right = new FormAttachment( 100, 0 ); 339 | fdExecute.top = new FormAttachment( gRegistry, margin ); 340 | gExecute.setLayoutData( fdExecute ); 341 | 342 | // Layout du tab 343 | FormData fdFileComp = new FormData(); 344 | fdFileComp.left = new FormAttachment( 0, 0 ); 345 | fdFileComp.top = new FormAttachment( 0, 0 ); 346 | fdFileComp.right = new FormAttachment( 100, 0 ); 347 | fdFileComp.bottom = new FormAttachment( 100, 0 ); 348 | compositeTabDubboClient.setLayoutData( fdFileComp ); 349 | 350 | compositeTabDubboClient.layout(); 351 | tabItemDubboClient.setControl( compositeTabDubboClient ); 352 | 353 | 354 | wTabFolder.setSelection( tabItemDubboClient ); 355 | 356 | 357 | FormData fdTabFolder = new FormData(); 358 | fdTabFolder.left = new FormAttachment( 0, 0 ); 359 | fdTabFolder.top = new FormAttachment( wStepname, margin ); 360 | fdTabFolder.right = new FormAttachment( 100, 0 ); 361 | fdTabFolder.bottom = new FormAttachment( 100, -50 ); 362 | wTabFolder.setLayoutData( fdTabFolder ); 363 | 364 | 365 | // Boutons OK / Cancel 366 | 367 | wOK = new Button( shell, SWT.PUSH ); 368 | wOK.setText( BaseMessages.getString( PKG, "System.Button.OK" ) ); 369 | 370 | wCancel = new Button( shell, SWT.PUSH ); 371 | wCancel.setText( BaseMessages.getString( PKG, "System.Button.Cancel" ) ); 372 | 373 | setButtonPositions( new Button[] { wOK, /*wAddInput, wAddOutput,*/ wCancel }, margin, wTabFolder ); 374 | 375 | // Detect X or ALT-F4 or something that kills this window... 376 | shell.addShellListener( new ShellAdapter() { 377 | public void shellClosed( ShellEvent e ) { 378 | cancel(); 379 | } 380 | } ); 381 | 382 | wOK.addSelectionListener( new SelectionAdapter() { 383 | public void widgetSelected( SelectionEvent e ) { 384 | ok(); 385 | } 386 | } ); 387 | 388 | wCancel.addSelectionListener( new SelectionAdapter() { 389 | public void widgetSelected( SelectionEvent e ) { 390 | cancel(); 391 | } 392 | } ); 393 | 394 | lsDef = new SelectionAdapter() { 395 | public void widgetDefaultSelected( SelectionEvent e ) { 396 | ok(); 397 | } 398 | }; 399 | 400 | loadCombo(); 401 | 402 | loadDataIntoToUI(); 403 | 404 | if(meta.getExecMethodArgTypes() != null) { 405 | addMethodArgsTab(); 406 | } 407 | 408 | setSize(); 409 | 410 | shell.open(); 411 | 412 | while ( !shell.isDisposed() ) { 413 | if ( !display.readAndDispatch() ) { 414 | display.sleep(); 415 | } 416 | } 417 | 418 | return stepname; 419 | } 420 | 421 | private void ok() { 422 | if (Const.isEmpty(wStepname.getText())) { 423 | return; 424 | } 425 | stepname = wStepname.getText(); // return value 426 | saveDataIntoMeta(); 427 | dispose(); 428 | } 429 | 430 | private void saveDataIntoMeta() { 431 | meta.setAppName(wAppName.getText()); 432 | meta.setRegistryAddr(wRegistryAddr.getText()); 433 | meta.setRegProtocol(wRegProtocol.getText()); 434 | meta.setExecProvider(wExecProvider.getText()); 435 | meta.setExecInterface(wExecInterface.getText()); 436 | meta.setExecMethodName(wExecMethod.getText()); 437 | 438 | TableItem[] tableItems = argsTableView.table.getItems(); 439 | String[] argValues = new String[tableItems.length]; 440 | for(int i = 0; i < tableItems.length; i++) { 441 | argValues[i] = tableItems[i].getText(3); 442 | } 443 | meta.setArgValues(argValues); 444 | } 445 | 446 | private void loadCombo() { 447 | Map dubboProviderServices = DubboClientMeta.dubboPrividerServices; 448 | Set providerSet = dubboProviderServices.keySet(); 449 | TreeSet treeSet = new TreeSet(providerSet); 450 | String[] providerNames = new String[treeSet.size()]; 451 | treeSet.toArray(providerNames); 452 | wExecProvider.setItems(providerNames); 453 | } 454 | 455 | private void loadDataIntoToUI() { 456 | wStepname.setText( stepname ); 457 | wAppName.setText(meta.getAppName() == null ? "" : meta.getAppName()); 458 | wRegistryAddr.setText(meta.getRegistryAddr() == null ? "" : meta.getRegistryAddr()); 459 | wRegProtocol.setText(meta.getRegProtocol() == null ? "" : meta.getRegProtocol()); 460 | wExecProvider.setText(meta.getExecProvider() == null ? "" : meta.getExecProvider()); 461 | wExecInterface.setText(meta.getExecInterface() == null ? "" : meta.getExecInterface()); 462 | wExecMethod.setText(meta.getExecMethodName() == null ? "" : meta.getExecMethodName()); 463 | } 464 | 465 | private void cancel() { 466 | stepname = null; 467 | meta.setChanged( changed ); 468 | dispose(); 469 | } 470 | 471 | private void onProviderSelected(SelectionEvent e) { 472 | CCombo _wExecProvider = (CCombo) e.getSource(); 473 | String selectProvider = _wExecProvider.getText(); 474 | meta.setExecProvider(selectProvider); 475 | // 加载接口 476 | String[] interfaceClassNames = DubboClientMeta.dubboPrividerServices.get(selectProvider); 477 | wExecInterface.setItems(interfaceClassNames); 478 | } 479 | 480 | private void onInterfaceSelected(SelectionEvent e) throws Exception { 481 | CCombo _wExecInterface = (CCombo) e.getSource(); 482 | String selectInterface = _wExecInterface.getText(); 483 | meta.setExecInterface(selectInterface); 484 | Class clazz = DubboClientMeta.dynaClassLoader.loadClass(selectInterface); 485 | // 加载调用方法 486 | List methods = ReflectionUtil.getInterfaceMethod(clazz); 487 | String[] methodNames = new String[methods.size()]; 488 | for(int i = 0; i < methodNames.length; i++) { 489 | methodNames[i] = methods.get(i).getName(); 490 | } 491 | wExecMethod.setItems(methodNames); 492 | 493 | meta.setAllMethods(methods); 494 | } 495 | 496 | // 选择"调用方法"时候触发的动作 497 | private void onMethodSelected(SelectionEvent e) { 498 | CCombo _wExecMethod = (CCombo) e.getSource(); 499 | int selIndex = _wExecMethod.getSelectionIndex(); 500 | Method selMethod = meta.getAllMethods().get(selIndex); 501 | meta.setExecMethodName(selMethod.getName()); 502 | meta.setExecMethod(selMethod); 503 | Class[] methodArgTypes = ReflectionUtil.getMethodArgTypes(selMethod); 504 | Class methodReturnType = ReflectionUtil.getMethodReturnType(selMethod); 505 | meta.setExecMethodArgTypes(methodArgTypes); 506 | meta.setExecMethodReturnType(methodReturnType); 507 | 508 | 509 | // 先移除 510 | removeMethodArgsTab(); 511 | // 再添加 512 | addMethodArgsTab(); 513 | } 514 | 515 | private void removeMethodArgsTab() { 516 | if(tabItemArgs != null) { 517 | tabItemArgs.dispose(); 518 | meta.setArgValues(null); 519 | 520 | argsTableView = null; 521 | tabItemArgs = null; 522 | } 523 | } 524 | 525 | private void addMethodArgsTab() { 526 | 527 | TableView oldTableView = argsTableView; 528 | int margin = Const.MARGIN; 529 | 530 | Composite vCompositeTabField = new Composite( wTabFolder, SWT.NONE ); 531 | FormLayout formLayout = new FormLayout(); 532 | formLayout.marginWidth = Const.FORM_MARGIN; 533 | formLayout.marginHeight = Const.FORM_MARGIN; 534 | 535 | vCompositeTabField.setLayout( formLayout ); 536 | props.setLook( vCompositeTabField ); 537 | 538 | if ( tabItemArgs == null ) { 539 | tabItemArgs = new CTabItem( wTabFolder, SWT.NONE ); 540 | } 541 | 542 | ColumnInfo colinf1 = new ColumnInfo("argName", ColumnInfo.COLUMN_TYPE_TEXT, false); 543 | colinf1.setReadOnly(true); 544 | ColumnInfo colinf2 = new ColumnInfo("argType", ColumnInfo.COLUMN_TYPE_TEXT, false); 545 | colinf2.setReadOnly(true); 546 | ColumnInfo colinf3 = new ColumnInfo("argVal", ColumnInfo.COLUMN_TYPE_TEXT, false); 547 | 548 | ColumnInfo[] colinf = new ColumnInfo[] { 549 | colinf1, 550 | colinf2, 551 | colinf3 552 | }; 553 | argsTableView = 554 | new TableView( transMeta, vCompositeTabField, SWT.FULL_SELECTION | SWT.MULTI, colinf, 1, lsMod, props ); 555 | argsTableView.setReadonly( false ); 556 | argsTableView.clearAll(); 557 | tabItemArgs.setText("args"); 558 | 559 | Button vButton = new Button( vCompositeTabField, SWT.NONE ); 560 | vButton.setText( BaseMessages.getString( PKG, "System.Button.GetFields" ) ); 561 | 562 | vButton.addSelectionListener(new SelectionAdapter() { 563 | // TODO 564 | }); 565 | 566 | Button[] buttons = new Button[] { vButton }; 567 | BaseStepDialog.positionBottomButtons( vCompositeTabField, buttons, Const.MARGIN, null ); 568 | 569 | FormData fdTable = new FormData(); 570 | fdTable.left = new FormAttachment( 0, 0 ); 571 | fdTable.top = new FormAttachment( 0, margin ); 572 | fdTable.right = new FormAttachment( 100, 0 ); 573 | fdTable.bottom = new FormAttachment( vButton, 0 ); 574 | argsTableView.setLayoutData( fdTable ); 575 | 576 | FormData fdInComp = new FormData(); 577 | fdInComp.left = new FormAttachment( 0, 0 ); 578 | fdInComp.top = new FormAttachment( 0, 0 ); 579 | fdInComp.right = new FormAttachment( 100, 0 ); 580 | fdInComp.bottom = new FormAttachment( 100, 0 ); 581 | vCompositeTabField.setLayoutData( fdInComp ); 582 | 583 | vCompositeTabField.layout(); 584 | 585 | tabItemArgs.setControl( vCompositeTabField ); 586 | 587 | if(meta.getExecMethodArgTypes() != null) { 588 | for(int i = 0; i < meta.getExecMethodArgTypes().length; i++) { 589 | Class argType = meta.getExecMethodArgTypes()[i]; 590 | TableItem vTableItem = new TableItem( argsTableView.table, SWT.NONE ); 591 | vTableItem.setText(1, "arg" + i); 592 | vTableItem.setText(2, argType.getCanonicalName()); 593 | if(meta.getArgValues() != null) { 594 | vTableItem.setText(3, meta.getArgValues()[i]); 595 | } 596 | } 597 | } 598 | 599 | if ( oldTableView != null ) { 600 | oldTableView.dispose(); 601 | } 602 | argsTableView.removeEmptyRows(); 603 | argsTableView.setRowNums(); 604 | argsTableView.optWidth( true ); 605 | } 606 | 607 | } 608 | -------------------------------------------------------------------------------- /src/com/gosun/di/ui/trans/steps/dubboclient/utils/DynamicClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.ui.trans.steps.dubboclient.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FilenameFilter; 6 | import java.lang.reflect.Method; 7 | import java.net.URL; 8 | import java.net.URLClassLoader; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.zip.ZipEntry; 12 | import java.util.zip.ZipInputStream; 13 | 14 | public class DynamicClassLoader { 15 | 16 | private URLClassLoader appClassLoader; 17 | private Method addURLMethod; 18 | 19 | private static class DynamicClassLoaderHolder { 20 | 21 | private static DynamicClassLoader instance; 22 | 23 | static { 24 | instance = new DynamicClassLoader(); 25 | } 26 | 27 | } 28 | 29 | public static DynamicClassLoader getDynamicClassLoader() { 30 | return DynamicClassLoaderHolder.instance; 31 | } 32 | 33 | private DynamicClassLoader() { 34 | appClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 35 | try { 36 | addURLMethod = ReflectionUtil.getMethod(URLClassLoader.class, "addURL", new Class[]{ 37 | URL.class 38 | }); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | 44 | public boolean loadJar(String[] jarFiles) { 45 | for(String jarFile : jarFiles) { 46 | if(!loadJar(jarFile)) { 47 | return false; 48 | } 49 | } 50 | return true; 51 | } 52 | 53 | public boolean loadJar(String jarFile) { 54 | File file = new File(jarFile); 55 | if(!file.exists()) { 56 | return false; 57 | } 58 | try { 59 | ReflectionUtil.invoke(addURLMethod, appClassLoader, file.toURI().toURL()); 60 | } catch(Exception e) { 61 | return false; 62 | } 63 | return true; 64 | } 65 | 66 | public Class loadClass(String name) throws ClassNotFoundException { 67 | return appClassLoader.loadClass(name); 68 | } 69 | 70 | /** 71 | * 在指定的jar文件里面查找所有的接口(包括包名) 72 | * @param jarFile 73 | * @return 74 | * @throws Exception 75 | */ 76 | public List findInterfacesInJar(String jarFile) { 77 | loadJar(jarFile); 78 | List interfaceNames = new ArrayList(); 79 | List classNames = null; 80 | try { 81 | classNames = listClassNamesFromJar(jarFile); 82 | } catch (Exception e1) { 83 | e1.printStackTrace(); 84 | } 85 | for(String className : classNames) { 86 | try { 87 | Class clazz = appClassLoader.loadClass(className); 88 | if(clazz.isInterface()) { 89 | interfaceNames.add(className); 90 | } 91 | } catch(Exception e) { 92 | System.out.println("有异常"); 93 | } finally { 94 | 95 | } 96 | } 97 | return interfaceNames; 98 | } 99 | 100 | /** 101 | * 加载指定目录下的所有jar到ClassLoader中 102 | * @param dir 103 | */ 104 | public void loadJarInDir(String dir) { 105 | String[] jarNames = findJarNamesInDir(dir); 106 | for(String jarName : jarNames) { 107 | String jarFile = dir + "/" + jarName; 108 | loadJar(jarFile); 109 | } 110 | } 111 | 112 | /** 113 | * 在指定目录中查找出所有的jar文件 114 | * @param dir 115 | * @return 116 | */ 117 | public String[] findJarNamesInDir(String dir) { 118 | String[] jarNames = null; 119 | File file = new File(dir); 120 | if(file.exists() && file.isDirectory()) { 121 | jarNames = file.list(new FilenameFilter() { 122 | 123 | @Override 124 | public boolean accept(File dir, String name) { 125 | if(name.endsWith(".jar")) { 126 | return true; 127 | } 128 | return false; 129 | } 130 | }); 131 | } 132 | return jarNames; 133 | } 134 | 135 | public List listClassNamesFromJar(String jarFile) throws Exception { 136 | List classNames = new ArrayList(); 137 | ZipInputStream zip = new ZipInputStream(new FileInputStream(jarFile)); 138 | for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) { 139 | if (!entry.isDirectory() && entry.getName().endsWith(".class")) { 140 | // This ZipEntry represents a class. Now, what class does it represent? 141 | String className = entry.getName().replace('/', '.'); // including ".class" 142 | classNames.add(className.substring(0, className.length() - ".class".length())); 143 | } 144 | } 145 | zip.close(); 146 | return classNames; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/com/gosun/di/ui/trans/steps/dubboclient/utils/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package com.gosun.di.ui.trans.steps.dubboclient.utils; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Modifier; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class ReflectionUtil { 9 | 10 | public static List getInterfaceMethod(Class interfaceClazz) { 11 | List result = new ArrayList(); 12 | Method[] methods = interfaceClazz.getMethods(); 13 | for(Method method : methods) { 14 | if(method.getModifiers() == (Modifier.PUBLIC + Modifier.ABSTRACT)) { 15 | result.add(method); 16 | } 17 | } 18 | return result; 19 | } 20 | 21 | public static Method getMethod(Class clazz, String methodName, Class[] methodArgTypes) throws Exception { 22 | Method method = null; 23 | if(clazz != null ) { 24 | method = clazz.getDeclaredMethod(methodName, methodArgTypes); 25 | } 26 | return method; 27 | } 28 | 29 | public static Class[] getMethodArgTypes(Method method) { 30 | Class[] paramTypes = method.getParameterTypes(); 31 | return paramTypes; 32 | } 33 | 34 | public static Class getMethodReturnType(Method method) { 35 | return method.getReturnType(); 36 | } 37 | 38 | public static Object invoke(Method method, Object obj, Object... args) throws Exception { 39 | method.setAccessible(true); 40 | return method.invoke(obj, args); 41 | } 42 | 43 | } 44 | --------------------------------------------------------------------------------