├── .github
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── kotlinc.xml
├── misc.xml
├── modules.xml
├── uiDesigner.xml
├── vcs.xml
└── workspace.xml
├── MVPHelper-master.iml
├── MVPHelper.iml
├── MVPHelper_v2_4_release.jar
├── README.md
├── README_EN.md
├── img
├── error_class_name.gif
├── error_package.gif
├── go_home_you_are_drunk.png
├── install_local.png
├── install_repositories.png
├── log.gif
├── mode_contract.gif
├── mode_presenter.gif
├── mvp_contract.gif
├── mvp_presenter.gif
├── step1.png
├── step2.png
└── suffix_support.gif
├── resources
├── META-INF
│ └── plugin.xml
└── string.properties
└── src
└── com
└── wingsofts
└── mvphelper
├── action
└── MvpHelperAction.java
├── biz
├── EventLogger.java
├── Startable.java
├── checker
│ ├── Checker.java
│ └── impl
│ │ └── EnvironmentChecker.java
├── config
│ ├── MvpConfigurable.java
│ └── impl
│ │ └── MvpConfig.java
├── dir
│ └── generator
│ │ ├── DirGenerator.java
│ │ └── impl
│ │ ├── BaseDirGenerator.java
│ │ ├── ContractModeDirGenerator.java
│ │ └── PresenterModeDirGenerator.java
└── file
│ └── generator
│ ├── FileGenerator.java
│ └── impl
│ ├── BaseFileGenerator.java
│ └── JavaModeFileGenerator.java
└── gui
├── MvpHelperConfigPanel.form
└── MvpHelperConfigPanel.java
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *If you are creating a new issue, make sure you could provide a piece of `bug report` / `stacktrace` / `screenshot`.*
2 | *It's a little bit hard to fix a bug according to a single sentence*
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /out/
2 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.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 |
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 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.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 |
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 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
234 |
235 |
236 |
237 | tostring
238 | tos
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 | true
282 | DEFINITION_ORDER
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 | AOP
305 |
306 |
307 | Abstraction issuesJava
308 |
309 |
310 | CDI(Contexts and Dependency Injection) issues
311 |
312 |
313 | CFML
314 |
315 |
316 | Code style issuesJava
317 |
318 |
319 | Concurrency annotation issuesJava
320 |
321 |
322 | Declaration redundancyJava
323 |
324 |
325 | Dependency issuesJava
326 |
327 |
328 | Encapsulation issuesJava
329 |
330 |
331 | FreeMarker inspections
332 |
333 |
334 | General
335 |
336 |
337 | GeneralJavaScript
338 |
339 |
340 | Groovy
341 |
342 |
343 | HTML
344 |
345 |
346 | Initialization issuesJava
347 |
348 |
349 | Internationalization issues
350 |
351 |
352 | Internationalization issuesJava
353 |
354 |
355 | JPA issues
356 |
357 |
358 | JSF annotated elements errors
359 |
360 |
361 | JSP Inspections
362 |
363 |
364 | Java
365 |
366 |
367 | Java 8Java language level migration aidsJava
368 |
369 |
370 | Java 9Java language level migration aidsJava
371 |
372 |
373 | Java language level migration aidsJava
374 |
375 |
376 | JavaFX
377 |
378 |
379 | JavaScript
380 |
381 |
382 | JavaScript validity issuesJavaScript
383 |
384 |
385 | Javadoc issuesJava
386 |
387 |
388 | Kotlin
389 |
390 |
391 | Maven
392 |
393 |
394 | Memory issuesJava
395 |
396 |
397 | Packaging issuesJava
398 |
399 |
400 | Plugin DevKit
401 |
402 |
403 | Potentially confusing code constructsGroovy
404 |
405 |
406 | Potentially confusing code constructsJavaScript
407 |
408 |
409 | Probable bugsJava
410 |
411 |
412 | Probable bugsKotlin
413 |
414 |
415 | RELAX NG
416 |
417 |
418 | RESTful Web Service
419 |
420 |
421 | RegExp
422 |
423 |
424 | SQL
425 |
426 |
427 | Spring
428 |
429 |
430 | Spring CoreSpring
431 |
432 |
433 | Spring MVCSpring
434 |
435 |
436 | Style issuesKotlin
437 |
438 |
439 | Threading issuesJava
440 |
441 |
442 | TypeScript
443 |
444 |
445 | WebSocket issues
446 |
447 |
448 | XML
449 |
450 |
451 | XMLSpring CoreSpring
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
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 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
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 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 | project
845 |
846 |
847 | true
848 |
849 |
850 |
851 | DIRECTORY
852 |
853 | false
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 | project
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 | 1473060314115
889 |
890 |
891 | 1473060314115
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 | 1493132904948
905 |
906 |
907 |
908 | 1493132904948
909 |
910 |
911 | 1493134585805
912 |
913 |
914 |
915 | 1493134585805
916 |
917 |
918 | 1493134773863
919 |
920 |
921 |
922 | 1493134773863
923 |
924 |
925 | 1493135278957
926 |
927 |
928 |
929 | 1493135278957
930 |
931 |
932 | 1493135815003
933 |
934 |
935 |
936 | 1493135815003
937 |
938 |
939 | 1493136971558
940 |
941 |
942 |
943 | 1493136971558
944 |
945 |
946 | 1493138211169
947 |
948 |
949 |
950 | 1493138211169
951 |
952 |
953 | 1493141262689
954 |
955 |
956 |
957 | 1493141262689
958 |
959 |
960 | 1493141758926
961 |
962 |
963 |
964 | 1493141758926
965 |
966 |
967 | 1493303012124
968 |
969 |
970 |
971 | 1493303012124
972 |
973 |
974 | 1493303049251
975 |
976 |
977 |
978 | 1493303049251
979 |
980 |
981 | 1493303087063
982 |
983 |
984 |
985 | 1493303087063
986 |
987 |
988 | 1493303717653
989 |
990 |
991 |
992 | 1493303717653
993 |
994 |
995 | 1493305389977
996 |
997 |
998 |
999 | 1493305389977
1000 |
1001 |
1002 | 1493305418660
1003 |
1004 |
1005 |
1006 | 1493305418660
1007 |
1008 |
1009 | 1493305441900
1010 |
1011 |
1012 |
1013 | 1493305441900
1014 |
1015 |
1016 | 1500469216207
1017 |
1018 |
1019 |
1020 | 1500469216207
1021 |
1022 |
1023 | 1500469536162
1024 |
1025 |
1026 |
1027 | 1500469536162
1028 |
1029 |
1030 | 1500469826220
1031 |
1032 |
1033 |
1034 | 1500469826220
1035 |
1036 |
1037 | 1500471830488
1038 |
1039 |
1040 |
1041 | 1500471830488
1042 |
1043 |
1044 | 1500472009089
1045 |
1046 |
1047 |
1048 | 1500472009089
1049 |
1050 |
1051 | 1521637095192
1052 |
1053 |
1054 |
1055 | 1521637095192
1056 |
1057 |
1058 | 1521637120659
1059 |
1060 |
1061 |
1062 | 1521637120659
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 |
1088 |
1089 |
1090 |
1091 |
1092 |
1093 |
1094 |
1095 |
1096 |
1097 |
1098 |
1099 |
1100 |
1101 |
1102 |
1103 |
1104 |
1105 |
1106 |
1107 |
1129 |
1130 |
1131 |
1132 |
1133 |
1134 |
1135 |
1136 |
1137 |
1138 |
1139 |
1140 |
1141 |
1142 |
1143 |
1144 |
1145 |
1146 |
1147 |
1148 |
1149 |
1150 |
1151 |
1152 |
1153 |
1154 |
1155 |
1156 |
1157 |
1158 |
1159 |
1160 |
1161 |
1162 |
1163 |
1164 |
1165 |
1166 |
1167 |
1168 |
1169 |
1170 |
1171 |
1172 |
1173 |
1174 |
1175 |
1176 |
1177 |
1178 |
1179 |
1180 |
1181 |
1182 |
1183 |
1184 |
1185 |
1186 |
1187 |
1188 |
1189 |
1190 |
1191 |
1192 |
1193 |
1194 |
1195 |
1196 |
1197 |
1198 |
1199 |
1200 |
1201 |
1202 |
1203 |
1204 |
1205 |
1206 |
1207 |
1208 |
1209 |
1210 |
1211 |
1212 |
1213 |
1214 |
1215 |
1216 |
1217 |
1218 |
1219 |
1220 |
1221 |
1222 |
1223 |
1224 |
1225 |
1226 |
1227 |
1228 |
1229 |
1230 |
1231 |
1232 |
1233 |
1234 |
1235 |
1236 |
1237 |
1238 |
1239 |
1240 |
1241 |
1242 |
1243 |
1244 |
1245 |
1246 |
1247 |
1248 |
1249 |
1250 |
1251 |
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |
1260 |
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 |
1268 |
1269 |
1270 |
1271 |
1272 |
1273 |
1274 |
1275 |
1276 |
1277 |
1278 |
1279 |
1280 |
1281 |
1282 |
1283 |
1284 |
1285 |
1286 |
1287 |
1288 |
1289 |
1290 |
1291 |
1292 |
1293 |
1294 |
1295 |
1296 |
1297 |
1298 |
1299 |
1300 |
1301 |
1302 |
1303 |
1304 |
1305 |
1306 |
1307 |
1308 |
1309 |
1310 |
1311 |
1312 |
1313 |
1314 |
1315 |
1316 |
1317 |
1318 |
1319 |
1320 |
1321 |
1322 |
1323 |
1324 |
1325 |
1326 |
1327 |
1328 |
1329 |
1330 |
1331 |
1332 |
1333 |
1334 |
1335 |
1336 |
1337 |
1338 |
1339 |
1340 |
1341 |
1342 |
1343 |
1344 |
1345 |
1346 |
1347 |
1348 |
1349 |
1350 |
1351 |
1352 |
1353 |
1354 |
1355 |
1356 |
1357 |
1358 |
1359 |
1360 |
1361 |
1362 |
1363 |
1364 |
1365 |
1366 |
1367 |
1368 |
1369 |
1370 |
1371 |
1372 |
1373 |
1374 |
1375 |
1376 |
1377 |
1378 |
1379 |
1380 |
1381 |
1382 |
1383 |
1384 |
1385 |
1386 |
1387 |
1388 |
1389 |
1390 |
1391 |
1392 |
1393 |
1394 |
1395 |
1396 |
1397 |
1398 |
1399 |
1400 |
1401 |
1402 |
1403 |
1404 |
1405 |
1406 |
1407 |
1408 |
1409 |
1410 |
1411 |
1412 |
1413 |
1414 |
1415 |
1416 |
1417 |
1418 |
1419 |
1420 |
1421 |
1422 |
1423 |
1424 |
1425 |
1426 |
1427 |
1428 |
1429 |
1430 |
1431 |
1432 |
1433 |
1434 |
1435 |
1436 |
1437 |
1438 |
1439 |
1440 |
1441 |
1442 |
1443 |
1444 |
1445 |
1446 |
1447 |
1448 |
1449 |
1450 |
1451 |
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 |
1479 |
1480 |
1481 |
1482 |
1483 |
1484 |
1485 |
1486 |
1487 |
1488 |
1489 |
1490 |
1491 |
1492 |
1493 |
1494 |
1495 |
1496 |
1497 |
1498 |
1499 |
1500 |
1501 |
1502 |
1503 |
1504 |
1505 |
1506 |
1507 |
1508 |
1509 |
1510 |
1511 |
1512 |
1513 |
1514 |
1515 |
1516 |
1517 |
1518 |
1519 |
1520 |
1521 |
1522 |
1523 |
1524 |
1525 |
1526 |
1527 |
1528 |
1529 |
1530 |
1531 |
1532 |
1533 |
1534 |
1535 |
1536 |
1537 |
1538 |
1539 |
1540 |
1541 |
1542 |
1543 |
1544 |
1545 |
1546 |
1547 |
1548 |
1549 |
1550 |
1551 |
1552 |
1553 |
1554 |
1555 |
1556 |
1557 |
1558 |
1559 |
1560 |
1561 |
1562 |
1563 |
1564 |
1565 |
1566 |
1567 |
1568 |
1569 |
1570 |
1571 |
1572 |
1573 |
1574 |
1575 |
1576 |
1577 |
1578 |
1579 |
1580 |
1581 |
1582 |
1583 |
1584 |
1585 |
1586 |
1587 |
1588 |
1589 |
1590 |
1591 |
1592 |
1593 |
1594 |
1595 |
1596 |
1597 |
1598 |
1599 |
1600 |
1601 |
1602 |
1603 |
1604 |
1605 |
1606 |
1607 |
1608 |
1609 |
1610 |
1611 |
1612 |
1613 |
1614 |
1615 |
1616 |
1617 |
1618 |
1619 |
1620 |
1621 |
1622 |
1623 |
1624 |
1625 |
1626 |
1627 |
1628 |
1629 |
1630 |
1631 |
1632 |
1633 |
1634 |
1635 |
1636 |
1637 |
1638 |
1639 |
1640 |
1641 |
1642 |
1643 |
1644 |
1645 |
1646 |
1647 |
1648 |
1649 |
1650 |
1651 |
1652 |
1653 |
1654 |
1655 |
1656 |
1657 | No facets are configured
1658 |
1659 |
1660 |
1661 |
1662 |
1663 |
1664 |
1665 |
1666 |
1667 |
1668 |
1669 | jquery-1.11.1
1670 |
1671 |
1672 |
1673 |
1674 |
1675 |
1676 |
1677 |
1678 |
1679 |
1680 |
1681 | IntelliJ IDEA IU-173.4674.33
1682 |
1683 |
1684 |
1685 |
1686 |
1687 |
1688 |
1689 |
1690 |
1691 |
1692 |
1693 | MVPHelper
1694 |
1695 |
1696 |
1697 |
1698 |
1699 |
1700 |
1701 |
1702 |
1703 |
1704 |
1705 |
1706 | IntelliJ IDEA Community Edition IC-162.1121.32
1707 |
1708 |
1709 |
1710 |
1711 |
1712 |
1713 |
1714 |
1715 |
1716 |
1717 |
1718 |
1719 |
1720 |
1721 |
1722 |
1723 |
1724 |
1725 |
1726 |
1727 |
1728 |
1729 |
--------------------------------------------------------------------------------
/MVPHelper-master.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MVPHelper.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/MVPHelper_v2_4_release.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/MVPHelper_v2_4_release.jar
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MvpHelper [English Document](/README_EN.md)
2 | 一款适用于 ```Intellij IDEA``` 和 ```Android Studio``` 的插件, 可用于为MVP架构生成接口以及实现类, 解放双手.
3 |
4 |
5 | 欢迎 ```Issue Report```, 欢迎 ```Feature Request```, 欢迎 ```Pull Request```
6 |
7 | 感谢[XieEDeHeiShou](https://github.com/XieEDeHeiShou) 提供重构后的代码以及特性跟进。
8 |
9 | ## 预览
10 | ```Contract``` 模式:
11 |
12 | 
13 |
14 | ```Presenter``` 模式(已设置后缀Impl):
15 |
16 | 
17 |
18 | 后缀支持:
19 |
20 | 
21 |
22 | 日志输出(气球偶尔会闪现一下,可以在Event Log里关闭):
23 |
24 | 
25 |
26 | 错误提示:
27 |
28 | 
29 |
30 | 
31 |
32 | ## 注意
33 | 对于MVP模式,定义一个 ```Contract``` 类来放置 ```Model``` , ```View``` , ```Presenter``` 的接口,将大大减少类文件。
34 | 将普通的接口替代如下:
35 |
36 | public interface GoodsInfoContract {
37 |
38 | interface View {
39 |
40 | }
41 | interface Presenter {
42 |
43 | }
44 | interface Model {
45 |
46 | }
47 |
48 | }
49 |
50 | ## 如何安装
51 | ### 在插件仓库搜索MvpHelper
52 | 
53 |
54 | ### 或者
55 | #### 第一步
56 | 下载[MvpHelper_v2_3_release.jar](MVPHelper_v2_4_release.jar)
57 | 或者前往 [releases](https://github.com/XieEDeHeiShou/MVPHelper/releases/latest)
58 |
59 | #### 第二步
60 | 安装插件
61 |
62 | 
63 |
64 | ## 如何使用
65 | 在 ```Contract``` 类或者 ```Presenter``` 类内部,点击 ```Generate``` 菜单或使用快捷键 ```Alt + Insert```,
66 | 选择 ```Mvp Helper``` 即可生成对应文件.
67 |
68 | ## 已知特性
69 | + 移除快捷键 ```Meta + 1```
70 | + 在非Java源文件中使用快捷键 ```Alt + Insert``` 时, MvpHelper菜单将不再出现
71 | + 不再限制根目录包名
72 | + 不再将 ```contract``` 包限制在根目录下, 并且支持sub-package
73 | 例如:
74 | >```com.example.project.package1.contract.package2.AContract```
75 | 将会生成 ```com.example.project.package1.model.package2.AModel```
76 | 以及 ```com.example.project.package1.presenter.package2.APresenter```
77 | + 当 ```AContract``` 位于 ```presenter``` 包下时将会出现错误提示而非继续生成错误的类
78 | + 支持File Header Template
79 | + 已实现 ```Contract``` 模式
80 | + ```Contract``` 所处的位置中必须有至少一个包以 ```contract``` 结尾
81 | + 强制 ```Contract``` 为 ```interface```
82 | + ```Contract``` 中的三个接口不包含多余的修饰符
83 | + 重复生成将删除旧文件并重新生成
84 | + 已实现 ```Presenter``` 模式
85 | + ```Presenter``` 所处的位置中必须有至少一个包以 ```presenter``` 结尾
86 | + 在 ```Presenter``` 中启动插件将复刻 ```Contract``` 模式下的实现方式
87 | + ```Presenter``` 模式在自定义后缀的情况下不会删除原有 ```Presenter```, 因此我们建议使用```Contract``` 模式
88 |
89 | ## TODO
90 | + 实现 ```Activity``` 模式
91 | + 实现 ```Fragment``` 模式
92 | + 将生成的文件自动添加到Git (考虑到要进一步学习Git的命令行语法等相关内容, 可能会鸽)
93 |
94 | ## 参考资源
95 | + [Intellij Platform SDK DevGuide](http://www.jetbrains.org/intellij/sdk/docs/)
96 | + [Persisting State of Components](http://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html)
97 | How to save and load plugin configs
98 | + [Customizing the IDEA Settings Dialog](https://confluence.jetbrains.com/display/IDEADEV/Customizing+the+IDEA+Settings+Dialog)
99 | + [IDEA Online Source Code](https://upsource.jetbrains.com/idea-ce)
100 | + [CreateClassAction](https://upsource.jetbrains.com/idea-ce/file/idea-ce-10df87d7a9840e5901d4901ac4fff7ba035501c2/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java)
101 | + [ApplicationConfigurable, ProjectConfigurable](http://corochann.com/intellij-plugin-development-introduction-applicationconfigurable-projectconfigurable-873.html)
102 | + [PersistStateComponent](http://corochann.com/intellij-plugin-development-introduction-persiststatecomponent-903.html)
103 | + [Java Api Sample](http://www.programcreek.com/java-api-examples/index.php)
104 | + [Moxun's bolg](https://moxun.me/archives/category/黑科技/idea插件开发) (中文博客)
105 | + [AndroidStudio/IDEA插件开发学习](http://www.jianshu.com/p/0117d4b1eb00) (中文博客)
106 |
107 | ## 更新日志
108 | ### v2.x版 -基于Intellij Open Api 实现 by [XieEDeHeiShou](https://github.com/XieEDeHeiShou)
109 | + 2017-07-19
110 | + 修复潜在的NPE异常(#20)
111 | + MvpHelper_v2_3_release.jar
112 | + 2017-04-27
113 | + 修复实现类修饰符异常 package-private -> public
114 | + 新增日志类EventLogger
115 | + MvpHelper_v2_2_release.jar
116 | + 2017-04-25
117 | + 实现配置信息的存取
118 | + 实现运行时加载配置信息
119 | + MvpHelper_v2_0_release.jar
120 | + 追加 用户指导.gif
121 | + 向[原仓库](https://github.com/githubwing/MVPHelper)请求合并
122 | + 在Android Studio 环境下测试Java项目与Android项目
123 | + 修复Merge后造成的 ```Contract``` 修饰符异常,强制生成后的 ```Contract``` 为 ```public interface PrefixContract```
124 | + 修复配置面板在销毁时触发的 ```AbstractMethodException```
125 | + MvpHelper_v2_1_release.jar
126 | + 2017-04-24
127 | + 实现配置面板布局
128 | + 实现 ```Presenter``` 模式下的包生成类 ```PresenterModeDirGenerator```
129 | + 抽取各功能实现类接口,重新分包
130 | + 基于Intellij Open Api 更新 ```Contract``` 而非以替换文本的方式更新
131 | + 强制 ```Contract``` 为 ```interface```
132 | + 移除 ```Contract``` 中接口的多余修饰符 ```public```
133 | + 2017-04-23
134 | + 实现在指定包下生成类文件, 并注入包信息
135 | + 实现让生成类实现特定接口
136 | + 更新README.CN.MD
137 | + 2017-04-15 更新对当前环境的判定规则
138 | + 2017-04-12 实现Action的可见性判定, 当用户尝试通过 ```Alt + Insert``` 启动插件时,
139 | 将判断当前环境是否为Java源文件环境, 当条件不成立时将不再显示插件动作
140 | + 2017-04-11 实现 ```DirGenerator``` 与 ```FileGenerator``` 用于分别生成 ```package``` 与 ```class```
141 | + 2017-04-10 实现 ```EnvironmentChecker``` 用于检查当前环境是否满足生成条件:
142 | + Java源文件的文件名是否以 ```Contract``` 结尾, 并处于 ```contract``` 包下
143 | + Java源文件的文件名是否以 ```Presenter``` 结尾, 并处于 ```presenter``` 包下
144 |
145 |
146 | ### v1.x版 -基于Java IO Api 实现 by [githubwing](https://github.com/githubwing)
147 | + 2017-04-10 将源文件分包并尝试重构
148 | + 2017-04-09 移除源文件中的 ```C``` 语言异味
149 | + 2017-04-06 分支自[原仓库](https://github.com/githubwing/MVPHelper), 并向源文件中追加注释, 以便阅读
150 |
151 | ## Eclipse
152 | 
153 |
154 | # License
155 |
156 | Copyright 2016 androidwing1992
157 |
158 | Licensed under the Apache License, Version 2.0 (the "License");
159 | you may not use this file except in compliance with the License.
160 | You may obtain a copy of the License at
161 |
162 | http://www.apache.org/licenses/LICENSE-2.0
163 |
164 | Unless required by applicable law or agreed to in writing, software
165 | distributed under the License is distributed on an "AS IS" BASIS,
166 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
167 | See the License for the specific language governing permissions and
168 | limitations under the License.
169 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | # NOTE THIS IS A TRANSLATED COPY OF [中文文档](/README.md), MAY OUT OF DATE.
2 |
3 | Thanks for [XieEDeHeiShou](https://github.com/XieEDeHeiShou)
4 | # MvpHelper
5 | A plugin that designed for ```Intellij IDEA``` and ```Android Studio```, used to generate Mvp interfaces and classes.
6 |
7 | ```Issue Report``` welcomed, ```Feature Request``` welcomed, ```Pull Request``` welcomed
8 |
9 | ## Preview
10 | ```Contract``` mode:
11 |
12 | 
13 |
14 | ```Presenter``` mode(with suffix 'Impl'):
15 |
16 | 
17 |
18 | Suffix support:
19 |
20 | 
21 |
22 | Log (unexpected balloon may appear, just disable it in the Event Log):
23 | 
24 |
25 | Error dialog:
26 |
27 | 
28 |
29 | 
30 |
31 | ## Note
32 | For Mvp, define an interface ```Contract``` to place ```Model``` , ```View``` , ```Presenter```
33 | will greatly reduce the number of source files:
34 |
35 | public interface GoodsInfoContract {
36 |
37 | interface View {
38 |
39 | }
40 | interface Presenter {
41 |
42 | }
43 | interface Model {
44 |
45 | }
46 |
47 | }
48 |
49 | ## How to install
50 | ### Search in the repositories with keyword:MvpHelper
51 | 
52 |
53 | ### Or install plugin.jar
54 | #### step1
55 | Download [MvpHelper_v2_3_release.jar](MVPHelper_v2_4_release.jar)
56 | or redirect to [releases](https://github.com/XieEDeHeiShou/MVPHelper/releases/latest)
57 |
58 | #### step2
59 | Install it.
60 |
61 | 
62 |
63 | ## How to use
64 | In ```Contract``` or ```Presenter``` ,click ```Generate``` menu or try hot-key ```Alt + Insert```,
65 | select ```Mvp Helper``` .
66 |
67 | ## Feature
68 | + Remove hot-key ```Meta + 1```
69 | + MvpHelper menu will not appear in un-java files when use hot key ```Alt + Insert```
70 | + No more root package limit (v1.0 only support com,org,me...)
71 | + No more ```contract``` package location limit, and support sub-package:
72 | >```com.example.project.package1.contract.package2.AContract```
73 | will generate ```com.example.project.package1.model.package2.AModel```
74 | and ```com.example.project.package1.presenter.package2.APresenter```
75 | + While ```AContract``` under ```presenter``` package, an error dialog will occur.(used to generate wrong files)
76 | + Support File Header Template
77 | + ```Contract``` mode achieved
78 | + ```Contract``` MUST under a path witch has at least one package END WITH ```contract```
79 | + Force ```Contract``` to be a ```public interface```
80 | + Remove unnecessary modifier form inner interfaces of ```Contract```
81 | + Re-generate will delete old files then generate new files.
82 | + ```Presenter``` mode achieved
83 | + ```Presenter``` MUST under a path witch has at least one package END WITH ```presenter```
84 | + When launch with```Presenter``` mode, it will call ```Contract``` mode later.
85 | + When launch with```Presenter``` mode with custom suffix, the old ```Presenter```, which without suffix,
86 | will not be delete automatically. So we recommend ```Contract``` mode.
87 | ## TODO
88 | + Achieve ```Activity``` mode
89 | + Achieve ```Fragment``` mode
90 | + Add generated files to git automatically (may take long time to learn command grammar of git)
91 |
92 | ## Related reference
93 | + [Intellij Platform SDK DevGuide](http://www.jetbrains.org/intellij/sdk/docs/)
94 | + [Persisting State of Components](http://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html)
95 | How to save and load plugin configs
96 | + [Customizing the IDEA Settings Dialog](https://confluence.jetbrains.com/display/IDEADEV/Customizing+the+IDEA+Settings+Dialog)
97 | + [IDEA Online Source Code](https://upsource.jetbrains.com/idea-ce)
98 | + [CreateClassAction](https://upsource.jetbrains.com/idea-ce/file/idea-ce-10df87d7a9840e5901d4901ac4fff7ba035501c2/java/java-impl/src/com/intellij/ide/actions/CreateClassAction.java)
99 | + [ApplicationConfigurable, ProjectConfigurable](http://corochann.com/intellij-plugin-development-introduction-applicationconfigurable-projectconfigurable-873.html)
100 | + [PersistStateComponent](http://corochann.com/intellij-plugin-development-introduction-persiststatecomponent-903.html)
101 | + [Java Api Sample](http://www.programcreek.com/java-api-examples/index.php)
102 | + [Moxun's bolg](https://moxun.me/archives/category/黑科技/idea插件开发) (Chinese blog)
103 | + [AndroidStudio/IDEA插件开发学习](http://www.jianshu.com/p/0117d4b1eb00) (Chinese blog)
104 |
105 | ## Change log
106 | ### v2.x -Based on Intellij Open Api, by [XieEDeHeiShou](https://github.com/XieEDeHeiShou)
107 | + 2017-07-19
108 | + Fix NPE(#20)
109 | + MvpHelper_v2_3_release.jar
110 | + 2017-04-27
111 | + Fix generated class modifier bug:package-private -> public
112 | + Add EventLogger
113 | + MvpHelper_v2_2_release.jar
114 | + 2017-04-25
115 | + Save and load configurations.
116 | + Load config while running.
117 | + MvpHelper_v2_0_release.jar
118 | + Add guide.gif
119 | + Pull request to [Original Repo](https://github.com/githubwing/MVPHelper)
120 | + Test under Android Studio Environment with Java project and Android project
121 | + Fix bug caused by merge: generated ```Contract``` lose ```public``` modifier, force to be ```public interface PrefixContract```
122 | + Fix ```AbstractMethodException``` caused by platform resource release
123 | + MvpHelper_v2_1_release.jar
124 | + 2017-04-24
125 | + Layout config panel
126 | + Achieve ```PresenterModeDirGenerator```
127 | + Extract interface, re-package
128 | + Change the way to update ```Contract```
129 | + force ```Contract``` to be ```interface```
130 | + Remove unnecessary modifier form inner interfaces of ```Contract```
131 | + 2017-04-23
132 | + Achieve file generation , package inject, support File Head Template
133 | + Achieve generated class implement special interface
134 | + Update README.CN.MD(Removed later)
135 | + 2017-04-15 Update Environment check rule
136 | + 2017-04-12 Achieve plugin visibility control, when launched by hot-key ```Alt + Insert```
137 | ,if current file is not a javaFile.java, the plugin menu will be invisible.
138 | + 2017-04-11 Achieve ```DirGenerator``` and ```FileGenerator``` used to generate dirs and files
139 | + 2017-04-10 Achieve ```EnvironmentChecker``` used to check plugin runtime condition:
140 | + Is the document END WITH ```Contract``` and UNDER a ```contract``` package
141 | + Is the document END WITH ```Presneter``` and UNDER a ```presenter``` package
142 |
143 | ### v1.x -Based on Java IO Api, by [githubwing](https://github.com/githubwing)
144 | + 2017-04-10 Try to rebuild the project with Intellij Open Api.
145 | + 2017-04-09 Remove ```C``` smell form original source code.
146 | + 2017-04-06 Fork form [original repe](https://github.com/githubwing/MVPHelper), add comment lines for reading.
147 |
148 | ## Eclipse
149 | 
150 |
151 | # License
152 |
153 | Copyright 2016 androidwing1992
154 |
155 | Licensed under the Apache License, Version 2.0 (the "License");
156 | you may not use this file except in compliance with the License.
157 | You may obtain a copy of the License at
158 |
159 | http://www.apache.org/licenses/LICENSE-2.0
160 |
161 | Unless required by applicable law or agreed to in writing, software
162 | distributed under the License is distributed on an "AS IS" BASIS,
163 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
164 | See the License for the specific language governing permissions and
165 | limitations under the License.
166 |
--------------------------------------------------------------------------------
/img/error_class_name.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/error_class_name.gif
--------------------------------------------------------------------------------
/img/error_package.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/error_package.gif
--------------------------------------------------------------------------------
/img/go_home_you_are_drunk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/go_home_you_are_drunk.png
--------------------------------------------------------------------------------
/img/install_local.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/install_local.png
--------------------------------------------------------------------------------
/img/install_repositories.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/install_repositories.png
--------------------------------------------------------------------------------
/img/log.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/log.gif
--------------------------------------------------------------------------------
/img/mode_contract.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/mode_contract.gif
--------------------------------------------------------------------------------
/img/mode_presenter.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/mode_presenter.gif
--------------------------------------------------------------------------------
/img/mvp_contract.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/mvp_contract.gif
--------------------------------------------------------------------------------
/img/mvp_presenter.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/mvp_presenter.gif
--------------------------------------------------------------------------------
/img/step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/step1.png
--------------------------------------------------------------------------------
/img/step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/step2.png
--------------------------------------------------------------------------------
/img/suffix_support.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/githubwing/MVPHelper/0119edea1bc1b78379050cdfb2523cb1c6a9641c/img/suffix_support.gif
--------------------------------------------------------------------------------
/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 | com.wingsofts.plugin.MVPHelper
3 |
4 |
5 |
6 | MVPHelper
7 | 2.4
8 |
9 |
11 |
14 |
15 | A plugin that helps you to create classes and interfaces for MVP.
16 | Click 'Generate' --> 'Mvp Helper' in Contract or Presenter class.
17 | For more detail see the link below.
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
36 |
37 |
--------------------------------------------------------------------------------
/resources/string.properties:
--------------------------------------------------------------------------------
1 | suffixTip=Whether implementation class's name has this suffix
2 | enableSuffix=Enable Suffix
3 | panelTitle=Mvp Helper Config Panel
4 | suffixExample=HelloWorldModel
5 | feedBackToGitHub=Feed back
6 | feedBackUrl=https://github.com/githubwing/MVPHelper/issues
7 | openOnGitHub=GitHub
8 | gitHubUrl=https://github.com/githubwing/MVPHelper
9 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/action/MvpHelperAction.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.action;
2 |
3 | import com.intellij.openapi.actionSystem.AnAction;
4 | import com.intellij.openapi.actionSystem.AnActionEvent;
5 | import com.intellij.openapi.actionSystem.CommonDataKeys;
6 | import com.intellij.openapi.actionSystem.Presentation;
7 | import com.intellij.openapi.editor.Editor;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.ui.Messages;
10 | import com.intellij.psi.PsiFile;
11 | import com.intellij.psi.PsiJavaFile;
12 | import com.wingsofts.mvphelper.biz.checker.Checker;
13 | import com.wingsofts.mvphelper.biz.checker.impl.EnvironmentChecker;
14 |
15 | /**
16 | * The entry of this plugin.
17 | *
18 | * If you want to contribute to this myProject, please follow
19 | * official tutorial.
20 | * Online source code is also available.
21 | *
22 | * CreateClassAction
23 | *
24 | *
25 | * @author DengChao
26 | * @since 2017/4/9
27 | */
28 | public class MvpHelperAction extends AnAction {
29 |
30 | @Override
31 | public void update(AnActionEvent event) {//before actionPerformed(AnActionEvent)
32 | super.update(event);
33 | //Set visibility only in case of existing project and editor
34 | Editor editor = event.getData(CommonDataKeys.EDITOR);
35 | Project project = event.getData(CommonDataKeys.PROJECT);
36 | //Set visibility only in '*.java' files.
37 | PsiFile psiFile = event.getData(CommonDataKeys.PSI_FILE);
38 |
39 | Presentation presentation = event.getPresentation();
40 | if (editor != null && project != null && psiFile instanceof PsiJavaFile) {
41 | presentation.setEnabledAndVisible(true);
42 | } else {
43 | presentation.setEnabledAndVisible(false);
44 | }
45 | }
46 |
47 | @Override
48 | public void actionPerformed(AnActionEvent event) {
49 | Checker checker = new EnvironmentChecker(event);
50 | if (!checker.hasSuffix()) {
51 | Messages.showErrorDialog(
52 | "Generation failed, " +
53 | "your class name MUST END WITH 'Contract' or 'Presenter'.",
54 | "Class Name Error");
55 | return;
56 | } else if (!checker.isInRightPlace()) {
57 | Messages.showErrorDialog(
58 | "You didn't place the 'Contract' or 'Presenter' under a right package.",
59 | "Package Error");
60 | return;
61 | }
62 | checker.start();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/EventLogger.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz;
2 |
3 | import com.intellij.notification.Notification;
4 | import com.intellij.notification.NotificationType;
5 | import com.intellij.notification.Notifications;
6 | import com.intellij.openapi.ui.popup.Balloon;
7 |
8 | /**
9 | * @author Administrator
10 | * @since 2017/4/27
11 | */
12 | public class EventLogger {
13 | private static final String GROUP_ID = "Mvp Helper";//The unique group id where "Event Log" could use to group your messages together.
14 | private static final String TITLE = "Mvp Helper Event Log";//The title on Balloon
15 |
16 | /**
17 | * Print log to "Event Log"
18 | */
19 | public static void log(String msg) {
20 | Notification notification = new Notification(GROUP_ID, TITLE, msg, NotificationType.INFORMATION);//build a notification
21 | //notification.hideBalloon();//didn't work
22 | Notifications.Bus.notify(notification);//use the default bus to notify (application level)
23 | Balloon balloon = notification.getBalloon();
24 | if (balloon != null) {//fix: #20 潜在的NPE
25 | balloon.hide(true);//try to hide the balloon immediately.
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/Startable.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz;
2 |
3 | /**
4 | * @author DengChao
5 | * @since 2017/4/24.
6 | */
7 | public interface Startable {
8 | /**
9 | * start everything =)
10 | */
11 | void start();
12 | }
13 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/checker/Checker.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.checker;
2 |
3 | import com.wingsofts.mvphelper.biz.Startable;
4 |
5 | /**
6 | * The interface witch provide methods to check if current document match all conditions
7 | *
8 | * @author DengChao
9 | * @since 2017/4/10
10 | */
11 | public interface Checker extends Startable {
12 | /**
13 | * Whether the class name end with 'Contract' or 'Presenter'
14 | */
15 | boolean hasSuffix();
16 |
17 | /**
18 | * Whether the document is in a proper package;
19 | */
20 | boolean isInRightPlace();
21 |
22 | /**
23 | * Start generation
24 | */
25 | void start();
26 |
27 | /**
28 | * The runtime mode.
29 | */
30 | enum Mode {
31 | CONTRACT, PRESENTER, ACTIVITY, FRAGMENT
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/checker/impl/EnvironmentChecker.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.checker.impl;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.actionSystem.CommonDataKeys;
5 | import com.intellij.psi.PsiJavaFile;
6 | import com.wingsofts.mvphelper.biz.checker.Checker;
7 | import com.wingsofts.mvphelper.biz.dir.generator.DirGenerator;
8 | import com.wingsofts.mvphelper.biz.dir.generator.impl.ContractModeDirGenerator;
9 | import com.wingsofts.mvphelper.biz.dir.generator.impl.PresenterModeDirGenerator;
10 |
11 | /**
12 | * The class used to check generation conditions and start file generation.
13 | *
14 | * @author Administrator
15 | * @since 2017/4/9
16 | */
17 | @SuppressWarnings("ConstantConditions")
18 | public class EnvironmentChecker implements Checker {
19 | private static final String CONTRACT = "Contract";
20 | private static final String PRESENTER = "Presenter";
21 | private final AnActionEvent actionEvent;
22 | private String className = "";//Never NPE, =)
23 | private String packageName = "";
24 | private Mode mode;
25 | private String prefix;
26 |
27 | public EnvironmentChecker(AnActionEvent actionEvent) {
28 | this.actionEvent = actionEvent;
29 | PsiJavaFile javaFile = (PsiJavaFile) actionEvent.getData(CommonDataKeys.PSI_FILE);
30 | packageName = javaFile.getPackageName();
31 | String fileName = javaFile.getName();
32 | className = fileName.substring(0, fileName.indexOf(".java"));
33 | }
34 |
35 | @Override
36 | public boolean hasSuffix() {
37 | if (className.endsWith(CONTRACT)) {
38 | mode = Mode.CONTRACT;
39 | prefix = className.replace(CONTRACT, "");
40 | return true;
41 | } else if (className.endsWith(PRESENTER)) {
42 | mode = Mode.PRESENTER;
43 | prefix = className.replace(PRESENTER, "");
44 | return true;
45 | }
46 | return false;
47 | }
48 |
49 | @Override
50 | public boolean isInRightPlace() {//split packageName by '.'
51 | String[] subPackages = packageName.split("\\.");
52 | if (mode == Mode.CONTRACT) {
53 | for (String subPackage : subPackages) {
54 | if (subPackage.endsWith("contract")) {
55 | return true;
56 | }
57 | }
58 | } else if (mode == Mode.PRESENTER) {
59 | for (String subPackage : subPackages) {
60 | if (subPackage.endsWith("presenter")) {
61 | return true;
62 | }
63 | }
64 | }//A Presenter-class not in presenter-package
65 | return false;
66 | }
67 |
68 | @Override
69 | public void start() {
70 | DirGenerator dirGenerator;
71 | if (mode == Mode.CONTRACT) {
72 | dirGenerator = new ContractModeDirGenerator(actionEvent, prefix);
73 | } else {// mode == Mode.PRESENTER
74 | dirGenerator = new PresenterModeDirGenerator(actionEvent, prefix);
75 | }
76 | dirGenerator.start();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/config/MvpConfigurable.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.config;
2 |
3 | /**
4 | * @author Administrator
5 | * @since 2017/4/25.
6 | */
7 | public interface MvpConfigurable {
8 | boolean hasSuffix();
9 |
10 | String getSuffix();
11 | }
12 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/config/impl/MvpConfig.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.config.impl;
2 |
3 | import com.intellij.openapi.project.Project;
4 | import com.wingsofts.mvphelper.biz.config.MvpConfigurable;
5 | import com.wingsofts.mvphelper.gui.MvpHelperConfigPanel;
6 |
7 | /**
8 | * @author Administrator
9 | * @since 2017/4/25.
10 | */
11 | public class MvpConfig implements MvpConfigurable {
12 |
13 | private final MvpConfigurable configurable;
14 |
15 | public MvpConfig(Project project) {
16 | configurable = new MvpHelperConfigPanel(project, false);
17 | }
18 |
19 | @Override
20 | public boolean hasSuffix() {
21 | return configurable.hasSuffix();
22 | }
23 |
24 | @Override
25 | public String getSuffix() {
26 | return configurable.getSuffix();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/dir/generator/DirGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.dir.generator;
2 |
3 | import com.wingsofts.mvphelper.biz.Startable;
4 |
5 | /**
6 | * @author Administrator
7 | * @since 2017/4/10
8 | */
9 | public interface DirGenerator extends Startable {
10 | }
11 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/dir/generator/impl/BaseDirGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.dir.generator.impl;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.intellij.openapi.actionSystem.CommonDataKeys;
5 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
6 | import com.intellij.openapi.command.WriteCommandAction;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.openapi.ui.Messages;
9 | import com.intellij.psi.PsiDirectory;
10 | import com.intellij.psi.PsiJavaFile;
11 | import com.wingsofts.mvphelper.biz.dir.generator.DirGenerator;
12 | import org.jetbrains.annotations.NotNull;
13 |
14 | import java.util.ResourceBundle;
15 |
16 | import static com.wingsofts.mvphelper.biz.EventLogger.log;
17 |
18 | /**
19 | * @author DengChao
20 | * @see #moveDirPointer(PsiDirectory, String)
21 | * @see #generateDirsBasedOnSuffix(String)
22 | * @see #onGenerateForkDirs(String)
23 | * @since 2017/4/24.
24 | */
25 | @SuppressWarnings({"ConstantConditions", "WeakerAccess"})
26 | abstract class BaseDirGenerator implements DirGenerator {
27 | protected final Project myProject;
28 | protected final String myPackageName;//where the action happens
29 | protected PsiDirectory myCurrentDir;//the base line of dir generation
30 | protected PsiDirectory myContractDir;
31 | protected PsiDirectory myModelDir;
32 | protected PsiDirectory myPresenterDir;
33 | protected String myPrefix;
34 |
35 | BaseDirGenerator(@NotNull AnActionEvent actionEvent, @NotNull String prefix) {
36 | this.myPrefix = prefix;
37 | myProject = actionEvent.getData(PlatformDataKeys.EDITOR).getProject();
38 |
39 | PsiJavaFile javaFile = (PsiJavaFile) actionEvent.getData(CommonDataKeys.PSI_FILE);
40 | myPackageName = javaFile.getPackageName();
41 | locateRootDir(javaFile.getContainingFile().getParent());
42 | }
43 |
44 | /**
45 | * Locate the root dir of current project.
46 | * For Android studio project, 'java' folder is always the root of any model by default.
47 | * For IDEA java project, 'src' folder is always the root of any model by default.
48 | *
49 | * @param currentDir where the action happens
50 | */
51 | private void locateRootDir(PsiDirectory currentDir) {
52 | String currentDirName = currentDir.getName();
53 | if (currentDirName.equals("java")
54 | || currentDirName.equals("src")) {
55 | myCurrentDir = currentDir;
56 | } else {
57 | PsiDirectory parent = currentDir.getParent();
58 | if (parent != null) {
59 | locateRootDir(parent);//if this folder is not the root, then try its parent.
60 | } else {
61 | //when there is no more parent, we reached the ROOT of a hard-disk...
62 | //if we still can't locate myCurrentDir by now...
63 | //I guess..not the plugin's fault.. =(
64 | Messages.showErrorDialog(
65 | "I can't imagine what happens to your project," +
66 | " technically, no project could reach here.\n" +
67 | " For your project match the IDEA's 'Java Project' definition," +
68 | " and it match our basic rule: 'Contract' under contract-package and 'Presenter' under presenter-package." +
69 | " Since it does happened, report us the detail please:" +
70 | " image of this dialog, image of your project structure tree, and your description\n" +
71 | ResourceBundle.getBundle("string").getString("feedBackUrl"),
72 | "Locate Root Dir Error");
73 | throw new RuntimeException("The plugin cannot find a root dir like \"java\" or \"src\"");
74 | }
75 | }
76 | }
77 |
78 | /**
79 | * Make sure to call this on sub-class#{@link #start()}'s first line
80 | *
81 | * @param suffix the suffix of the package witch used to determine where should have a fork.
82 | */
83 | protected void generateDirsBasedOnSuffix(@NotNull String suffix) {
84 | boolean isForkDirGenerated = false;
85 | String[] subPackages = myPackageName.split("\\.");
86 | for (String subPackage : subPackages) {
87 | if (!subPackage.endsWith(suffix)) {//if the package does not end with 'contract':
88 | if (isForkDirGenerated) {// and the 'presenter' and 'model' dir already generated,
89 | myContractDir = moveDirPointer(myContractDir, subPackage);
90 | myModelDir = moveDirPointer(myModelDir, subPackage);
91 | myPresenterDir = moveDirPointer(myPresenterDir, subPackage);
92 | }// but the 'presenter' and 'model' dir has not been generated,
93 | } else {
94 | onGenerateForkDirs(subPackage);
95 | isForkDirGenerated = true;//update the flag
96 | }
97 | //the current dir is the base line, so
98 | //no matter what happens, move myCurrentDir pointer to it's child;
99 | myCurrentDir = moveDirPointer(myCurrentDir, subPackage);
100 | }
101 | }
102 |
103 | /**
104 | * Move the pointer to it's sub-package.
105 | * sub-package will be generate if it's not exist.
106 | *
107 | * @param subPackage the sub-package's name
108 | */
109 | @NotNull
110 | protected PsiDirectory moveDirPointer(@NotNull final PsiDirectory currentDir, @NotNull final String subPackage) {
111 | final PsiDirectory[] subDirectory = {currentDir.findSubdirectory(subPackage)};
112 | if (subDirectory[0] == null) {
113 | WriteCommandAction.runWriteCommandAction(currentDir.getProject(), () -> {
114 | subDirectory[0] = currentDir.createSubdirectory(subPackage);
115 | log("BaseDirGenerator: " + currentDir.getVirtualFile().getPath() + "/" + subPackage + " generated");
116 | });
117 | }
118 | return subDirectory[0];
119 | }
120 |
121 | /**
122 | * Here the fork appears, sub-class have to implement this method to achieve particular work.
123 | * For example: subPackage = "Acontract"
124 | * Then this method should
125 | *
126 | * - Move {@link #myContractDir} to {@link #myCurrentDir}.subPackage
127 | * - Move {@link #myModelDir} to "Amodel"
128 | * - Move {@link #myPresenterDir} to "Apresenter"
129 | *
130 | *
131 | * @param subPackage the name of the dir which should have siblings
132 | * @see #moveDirPointer(PsiDirectory, String)
133 | */
134 | protected abstract void onGenerateForkDirs(@NotNull String subPackage);
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/dir/generator/impl/ContractModeDirGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.dir.generator.impl;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.wingsofts.mvphelper.biz.file.generator.impl.JavaModeFileGenerator;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | /**
8 | * @author Administrator
9 | * @since 2017/4/9
10 | */
11 | public class ContractModeDirGenerator extends BaseDirGenerator {
12 |
13 | public ContractModeDirGenerator(AnActionEvent actionEvent, String prefix) {
14 | super(actionEvent, prefix);
15 | }
16 |
17 | /**
18 | * start generation
19 | */
20 | @Override
21 | public void start() {
22 | generateDirsBasedOnSuffix("contract");
23 |
24 | new JavaModeFileGenerator(myProject, myContractDir, myModelDir, myPresenterDir, myPrefix).start();
25 | }
26 |
27 | @Override
28 | protected void onGenerateForkDirs(@NotNull String subPackage) {
29 | String prefix = subPackage.replace("contract", "");
30 | String subPackageM = prefix + "model";
31 | String subPackageP = prefix + "presenter";//if prefix exist.
32 | myContractDir = myCurrentDir.findSubdirectory(subPackage);
33 | myModelDir = moveDirPointer(myCurrentDir, subPackageM);
34 | myPresenterDir = moveDirPointer(myCurrentDir, subPackageP);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/dir/generator/impl/PresenterModeDirGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.dir.generator.impl;
2 |
3 | import com.intellij.openapi.actionSystem.AnActionEvent;
4 | import com.wingsofts.mvphelper.biz.file.generator.impl.JavaModeFileGenerator;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | /**
8 | * @author Administrator
9 | * @since 2017/4/9
10 | */
11 | public class PresenterModeDirGenerator extends BaseDirGenerator {
12 |
13 | public PresenterModeDirGenerator(AnActionEvent actionEvent, String prefix) {
14 | super(actionEvent, prefix);
15 | }
16 |
17 | /**
18 | * start generation
19 | */
20 | @Override
21 | public void start() {
22 | generateDirsBasedOnSuffix("presenter");
23 |
24 | new JavaModeFileGenerator(myProject, myContractDir, myModelDir, myPresenterDir, myPrefix).start();
25 | }
26 |
27 | @Override
28 | protected void onGenerateForkDirs(@NotNull String subPackage) {
29 | String prefix = subPackage.replace("presenter", "");
30 | String subPackageM = prefix + "model";
31 | String subPackageC = prefix + "contract";//if prefix exist.
32 | myContractDir = moveDirPointer(myCurrentDir, subPackageC);
33 | myModelDir = moveDirPointer(myCurrentDir, subPackageM);
34 | myPresenterDir = myCurrentDir.findSubdirectory(subPackage);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/file/generator/FileGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.file.generator;
2 |
3 | import com.wingsofts.mvphelper.biz.Startable;
4 |
5 | /**
6 | * The interface witch provide methods to start files and contents.
7 | *
8 | * @author DengChao
9 | * @since 2017/4/10
10 | */
11 | public interface FileGenerator extends Startable {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/file/generator/impl/BaseFileGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.file.generator.impl;
2 |
3 | import com.intellij.ide.fileTemplates.JavaTemplateUtil;
4 | import com.intellij.openapi.command.WriteCommandAction;
5 | import com.intellij.openapi.project.Project;
6 | import com.intellij.openapi.vfs.VirtualFile;
7 | import com.intellij.psi.*;
8 | import com.intellij.psi.search.GlobalSearchScope;
9 | import com.intellij.psi.search.PsiShortNamesCache;
10 | import com.wingsofts.mvphelper.biz.config.MvpConfigurable;
11 | import com.wingsofts.mvphelper.biz.config.impl.MvpConfig;
12 | import com.wingsofts.mvphelper.biz.file.generator.FileGenerator;
13 |
14 | import static com.wingsofts.mvphelper.biz.EventLogger.log;
15 |
16 | /**
17 | * The base file generator, provide basic functions for child-class.
18 | *
19 | * @author Administrator
20 | * @since 2017/4/24.
21 | */
22 | @SuppressWarnings({"ConstantConditions", "WeakerAccess"})
23 | abstract class BaseFileGenerator implements FileGenerator {
24 | protected Project myProject;//current java project
25 | protected PsiDirectory myContractDir;//the contract package dir
26 | protected PsiDirectory myModelDir;//the model package dir
27 | protected PsiDirectory myPresenterDir;//the presenter package dir
28 | protected String myPrefix;//the prefix used to identify each other
29 | protected PsiElementFactory myFactory;//the factory used to generate interface/class/innerClass/classReference
30 | protected JavaDirectoryService myDirectoryService;//the dirService used to generate files under particular dir(package)
31 | protected PsiShortNamesCache myShortNamesCache;//used to search a class in particular scope
32 | protected GlobalSearchScope myProjectScope;//just this project is enough
33 | private MvpConfigurable myConfig;
34 |
35 | BaseFileGenerator(Project project, PsiDirectory contractDir, PsiDirectory modelDir, PsiDirectory presenterDir, String prefix) {
36 | this.myProject = project;
37 | this.myContractDir = contractDir;
38 | this.myModelDir = modelDir;
39 | this.myPresenterDir = presenterDir;
40 | this.myPrefix = prefix;
41 | myShortNamesCache = PsiShortNamesCache.getInstance(project);
42 | myFactory = JavaPsiFacade.getElementFactory(project);
43 | myDirectoryService = JavaDirectoryService.getInstance();
44 | myProjectScope = GlobalSearchScope.projectScope(project);
45 | myConfig = new MvpConfig(project);
46 | }
47 |
48 | /**
49 | * Generate a java file
50 | *
51 | * @param directory the directory to place the file
52 | * @param fileName the name of the file tobe generate
53 | * @param type the type of the file
54 | * @param listener when the file has been generated, then the listener will be called.
55 | * @see JavaTemplateUtil#INTERNAL_CLASS_TEMPLATES
56 | */
57 | protected void generateFile(final PsiDirectory directory, final String fileName, final String type, final OnFileGeneratedListener listener) {
58 | WriteCommandAction.runWriteCommandAction(myProject, () -> {
59 | String fixedFileName = fileName;
60 | if (myConfig.hasSuffix() && type.equals(JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME)) {
61 | //only sub-class need to fix name
62 | fixedFileName += myConfig.getSuffix();
63 | }
64 |
65 | PsiClass[] psiClasses = myShortNamesCache.getClassesByName(fixedFileName, myProjectScope);//NotNull
66 | PsiClass psiClass;
67 | PsiJavaFile javaFile;
68 | VirtualFile virtualFile = directory.getVirtualFile();// VirtualDirectoryImpl
69 | String virtualFilePath;
70 | for (PsiClass aClass : psiClasses) {
71 | javaFile = (PsiJavaFile) aClass.getContainingFile();
72 | virtualFilePath = virtualFile.getPath();
73 | if (virtualFilePath.endsWith(javaFile.getPackageName().replaceAll("\\.", "/"))) {//if the class already exist.
74 | javaFile = (PsiJavaFile) aClass.getContainingFile();
75 | javaFile.delete();//then delete the old one
76 | log("BaseFileGenerator: " + virtualFilePath + "/" + fixedFileName + " old file deleted");
77 | }
78 | }//and re-generate one
79 |
80 | psiClass = myDirectoryService.createClass(directory, fixedFileName, type);
81 | javaFile = (PsiJavaFile) psiClass.getContainingFile();
82 | PsiPackage psiPackage = myDirectoryService.getPackage(directory);
83 | javaFile.setPackageName(psiPackage.getQualifiedName());
84 | log("BaseFileGenerator: " + psiClass.getQualifiedName() + " generated");
85 | listener.onJavaFileGenerated(javaFile, psiClass);
86 | });
87 | }
88 |
89 |
90 | @FunctionalInterface
91 | protected interface OnFileGeneratedListener {
92 | /**
93 | * When the file has been generated, then the listener will be called.
94 | *
95 | * @param javaFile the PsiJavaFile generated just now
96 | * @param psiClass the corresponding PsiClass
97 | */
98 | void onJavaFileGenerated(PsiJavaFile javaFile, PsiClass psiClass);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/biz/file/generator/impl/JavaModeFileGenerator.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.biz.file.generator.impl;
2 |
3 | import com.intellij.ide.fileTemplates.JavaTemplateUtil;
4 | import com.intellij.openapi.fileEditor.FileEditorManager;
5 | import com.intellij.openapi.fileEditor.OpenFileDescriptor;
6 | import com.intellij.openapi.project.Project;
7 | import com.intellij.psi.PsiClass;
8 | import com.intellij.psi.PsiDirectory;
9 |
10 | /**
11 | * The file generator works in Contract/Presenter Mode.
12 | *
13 | * @author DengChao
14 | * @since 2017/4/10
15 | */
16 | @SuppressWarnings("ConstantConditions")
17 | public class JavaModeFileGenerator extends BaseFileGenerator {
18 |
19 | public JavaModeFileGenerator(Project project, PsiDirectory contractDir, PsiDirectory modelDir, PsiDirectory presenterDir, String prefix) {
20 | super(project, contractDir, modelDir, presenterDir, prefix);
21 | }
22 |
23 | @Override
24 | public void start() {
25 | generateFile(myContractDir, myPrefix + "Contract", JavaTemplateUtil.INTERNAL_INTERFACE_TEMPLATE_NAME, (javaFile, psiClass) -> {
26 | PsiClass model = myFactory.createInterface("Model");
27 | PsiClass view = myFactory.createInterface("View");//You have to achieve 'View' yourself.
28 | PsiClass presenter = myFactory.createInterface("Presenter");
29 |
30 | model.getModifierList().setModifierProperty("public", false);//Remove modifier
31 | view.getModifierList().setModifierProperty("public", false);
32 | presenter.getModifierList().setModifierProperty("public", false);
33 |
34 | psiClass.add(model);
35 | psiClass.add(view);
36 | psiClass.add(presenter);
37 | psiClass.getModifierList().setModifierProperty("public", true);//force 'public interface myPrefixContract'
38 |
39 | FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
40 | OpenFileDescriptor fileDescriptor = new OpenFileDescriptor(myProject, javaFile.getVirtualFile());
41 | fileEditorManager.openTextEditor(fileDescriptor, true);//Open the Contract
42 |
43 | generateModel();
44 | generatePresenter();
45 | });
46 | }
47 |
48 | private void generatePresenter() {
49 | generateFile(myPresenterDir, myPrefix + "Presenter", JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME, (javaFile, psiClass) -> {
50 | PsiClass contractClass = myShortNamesCache.getClassesByName(myPrefix + "Contract", myProjectScope)[0];
51 | PsiClass presenter = contractClass.findInnerClassByName("Presenter", false);//don't need to search base
52 | psiClass.getImplementsList().add(myFactory.createClassReferenceElement(presenter));
53 | psiClass.getModifierList().setModifierProperty("public", true);//force 'public interface myPrefixContract'
54 | });
55 | }
56 |
57 | private void generateModel() {
58 | generateFile(myModelDir, myPrefix + "Model", JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME, (javaFile, psiClass) -> {
59 | PsiClass contractClass = myShortNamesCache.getClassesByName(myPrefix + "Contract", myProjectScope)[0];
60 | PsiClass model = contractClass.findInnerClassByName("Model", false);//don't need to search base
61 | psiClass.getImplementsList().add(myFactory.createClassReferenceElement(model));
62 | psiClass.getModifierList().setModifierProperty("public", true);//force 'public interface myPrefixContract'
63 | });
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/gui/MvpHelperConfigPanel.form:
--------------------------------------------------------------------------------
1 |
2 |
91 |
--------------------------------------------------------------------------------
/src/com/wingsofts/mvphelper/gui/MvpHelperConfigPanel.java:
--------------------------------------------------------------------------------
1 | package com.wingsofts.mvphelper.gui;
2 |
3 | import com.intellij.ide.util.PropertiesComponent;
4 | import com.intellij.openapi.components.State;
5 | import com.intellij.openapi.components.Storage;
6 | import com.intellij.openapi.options.Configurable;
7 | import com.intellij.openapi.options.UnnamedConfigurable;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.ui.Messages;
10 | import com.wingsofts.mvphelper.biz.config.MvpConfigurable;
11 | import org.jetbrains.annotations.Nls;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | import javax.swing.*;
15 | import javax.swing.event.CaretEvent;
16 | import java.awt.*;
17 | import java.awt.event.MouseAdapter;
18 | import java.awt.event.MouseEvent;
19 | import java.net.URI;
20 | import java.util.ResourceBundle;
21 |
22 | /**
23 | * @author DengChao
24 | * @since 2017/4/24
25 | */
26 | @State(name = "MvpHelperConfig", storages = {@Storage("MvpHelperConfig.xml")})//try register a storage place
27 | public class MvpHelperConfigPanel implements Configurable, MvpConfigurable {
28 | private static final String PREFIX = "MVP_HELPER_";
29 | private static final String KEY_HAS_SUFFIX = PREFIX + "KEY_HAS_SUFFIX";
30 | private static final String KEY_SUFFIX = PREFIX + "KEY_SUFFIX";
31 | private ResourceBundle string;//the static resource bundle
32 | private PropertiesComponent properties;//the properties object, used to save and load property.
33 | private String helloWorldModel;
34 | private String suffix;
35 | private JCheckBox ckEnableSuffix;
36 | private JTextField tfSuffixTemplate;
37 | private JTextArea taSuffixExample;
38 | private JLabel lFeedBack;
39 | private JLabel lOpenOnGitHub;
40 | private JPanel panel;
41 | private boolean hasSuffix;
42 | private boolean hasSuffixNewValue;
43 |
44 | /**
45 | * Constructor for Intellij Platform usage
46 | */
47 | @SuppressWarnings("unused")
48 | public MvpHelperConfigPanel(Project project) {
49 | this(project, true);
50 | }
51 |
52 | /**
53 | * Constructor for User usage
54 | *
55 | * @param project the project witch need to save and load config
56 | * @param fullInit is all Swing object need to init listeners
57 | */
58 | public MvpHelperConfigPanel(Project project, boolean fullInit) {
59 | string = ResourceBundle.getBundle("string");
60 | properties = PropertiesComponent.getInstance(project);//always project level.
61 | helloWorldModel = string.getString("suffixExample");
62 |
63 | hasSuffixNewValue = hasSuffix = properties.getBoolean(KEY_HAS_SUFFIX);//they are the same when init
64 | suffix = hasSuffix ? properties.getValue(KEY_SUFFIX) : "";//init update
65 |
66 | if (!fullInit) {
67 | return;
68 | }
69 |
70 | ckEnableSuffix.addItemListener(event -> {
71 | hasSuffixNewValue = ckEnableSuffix.isSelected();//then user changed the new value
72 | tfSuffixTemplate.setFocusable(hasSuffixNewValue);
73 | tfSuffixTemplate.setEnabled(hasSuffixNewValue);
74 |
75 | //no matter enable or disable, just reset the suffix template
76 | tfSuffixTemplate.setText("");
77 | taSuffixExample.setText(helloWorldModel);
78 | });
79 |
80 | tfSuffixTemplate.addCaretListener((CaretEvent caretEvent) ->
81 | taSuffixExample.setText(helloWorldModel + tfSuffixTemplate.getText()));//dynamic update
82 |
83 | ckEnableSuffix.setSelected(hasSuffix);
84 | tfSuffixTemplate.setEnabled(hasSuffix);
85 | tfSuffixTemplate.setFocusable(hasSuffix);
86 | taSuffixExample.setText(helloWorldModel + suffix);
87 |
88 | lFeedBack.addMouseListener(new MouseAdapter() {
89 | @Override
90 | public void mouseClicked(MouseEvent e) {
91 | String feedBackUrl = string.getString("feedBackUrl");
92 | try {
93 | Desktop.getDesktop().browse(URI.create(feedBackUrl));
94 | } catch (Exception exception) {
95 | Messages.showErrorDialog(
96 | "Oh..It seems we cannot open any browser on this platform automatically." +
97 | " But you could do it yourself:\n" +
98 | feedBackUrl, "Browse Error");
99 | exception.printStackTrace();
100 | }
101 | }
102 |
103 | });
104 |
105 | lOpenOnGitHub.addMouseListener(new MouseAdapter() {
106 | @Override
107 | public void mouseClicked(MouseEvent e) {
108 | String gitHubUrl = string.getString("gitHubUrl");
109 | try {
110 | Desktop.getDesktop().browse(URI.create(gitHubUrl));
111 | } catch (Exception exception) {
112 | Messages.showErrorDialog(
113 | "Oh..It seems we cannot open any browser on this platform automatically." +
114 | " But you could do it yourself:\n" +
115 | gitHubUrl, "Browse Error");
116 | exception.printStackTrace();
117 | }
118 | }
119 | });
120 | }
121 |
122 | @Nls
123 | @Override
124 | public String getDisplayName() {
125 | return "Mvp Helper";
126 | }
127 |
128 | @Nullable
129 | @Override
130 | public JComponent createComponent() {
131 | return panel;
132 | }
133 |
134 | @Override
135 | public boolean isModified() {
136 | return hasSuffix != hasSuffixNewValue || !suffix.equals(tfSuffixTemplate.getText());
137 | }
138 |
139 | @Override
140 | public void reset() {
141 | ckEnableSuffix.setSelected(hasSuffix);
142 | tfSuffixTemplate.setText(suffix);
143 | taSuffixExample.setText(helloWorldModel + suffix);
144 |
145 | properties.setValue(KEY_HAS_SUFFIX, hasSuffix);
146 | properties.setValue(KEY_SUFFIX, suffix);
147 | }
148 |
149 | @Override
150 | public void apply() {
151 | String suffixNewValue = tfSuffixTemplate.getText();
152 | properties.setValue(KEY_HAS_SUFFIX, hasSuffixNewValue);
153 | properties.setValue(KEY_SUFFIX, suffixNewValue);
154 |
155 | hasSuffix = hasSuffixNewValue;//update isModified()
156 | suffix = suffixNewValue;
157 | }
158 |
159 | /**
160 | * Override this to avoid AbstractMethodException,
161 | * for the IDEA plugin dev-platform use Java 8's feature: default interface
162 | *
163 | * @see UnnamedConfigurable#disposeUIResources()
164 | */
165 | @Override
166 | public void disposeUIResources() {
167 | //noinspection BoundFieldAssignment
168 | panel = null;
169 | }
170 |
171 | /**
172 | * Only available in MvpHelperConfigPanel(project,false)
173 | */
174 | @Override
175 | public String getSuffix() {
176 | return suffix;
177 | }
178 |
179 | /**
180 | * Only available in MvpHelperConfigPanel(project,false)
181 | */
182 | @Override
183 | public boolean hasSuffix() {
184 | return hasSuffix;
185 | }
186 |
187 | }
188 |
--------------------------------------------------------------------------------