1 19 20 package org.netbeans.modules.junit; 21 22 import java.io.IOException ; 23 import java.net.URL ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.HashSet ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import javax.lang.model.element.TypeElement; 33 import org.netbeans.api.java.classpath.ClassPath; 34 import org.netbeans.api.java.queries.UnitTestForSourceQuery; 35 import org.netbeans.api.java.source.ElementHandle; 36 import org.netbeans.api.java.source.JavaSource; 37 import org.netbeans.modules.junit.TestabilityResult.SkippedClass; 38 import org.netbeans.modules.junit.plugin.JUnitPlugin; 39 import org.netbeans.modules.junit.plugin.JUnitPlugin.CreateTestParam; 40 import org.netbeans.modules.junit.plugin.JUnitPlugin.Location; 41 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 42 import org.openide.DialogDisplayer; 43 import org.openide.ErrorManager; 44 import org.openide.NotifyDescriptor; 45 import org.openide.cookies.SaveCookie; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileUtil; 48 import org.openide.filesystems.Repository; 49 import org.openide.loaders.DataFolder; 50 import org.openide.loaders.DataObject; 51 import org.openide.loaders.DataObjectNotFoundException; 52 import org.openide.util.Mutex; 53 import org.openide.util.NbBundle; 54 import static javax.lang.model.util.ElementFilter.methodsIn; 55 import static javax.lang.model.util.ElementFilter.typesIn; 56 import static org.netbeans.api.java.classpath.ClassPath.SOURCE; 57 import static org.netbeans.api.java.classpath.ClassPath.COMPILE; 58 import static org.netbeans.api.java.classpath.ClassPath.BOOT; 59 61 66 public final class DefaultPlugin extends JUnitPlugin { 67 68 71 protected Location getTestLocation(Location sourceLocation) { 72 FileObject fileObj = sourceLocation.getFileObject(); 73 ClassPath srcCp; 74 75 if ((srcCp = ClassPath.getClassPath(fileObj, SOURCE)) == null) { 76 return null; 77 } 78 79 String baseResName = srcCp.getResourceName(fileObj, '/', false); 80 String testResName = !fileObj.isFolder() 81 ? getTestResName(baseResName, fileObj.getExt()) 82 : getSuiteResName(baseResName); 83 assert testResName != null; 84 85 return getOppositeLocation(sourceLocation, 86 srcCp, 87 testResName, 88 true); 89 } 90 91 94 protected Location getTestedLocation(Location testLocation) { 95 FileObject fileObj = testLocation.getFileObject(); 96 ClassPath srcCp; 97 98 if (fileObj.isFolder() 99 || ((srcCp = ClassPath.getClassPath(fileObj, SOURCE)) == null)) { 100 return null; 101 } 102 103 String baseResName = srcCp.getResourceName(fileObj, '/', false); 104 String srcResName = getSrcResName(baseResName, fileObj.getExt()); 105 if (srcResName == null) { 106 return null; } 108 109 return getOppositeLocation(testLocation, 110 srcCp, 111 srcResName, 112 false); 113 } 114 115 118 private static Location getOppositeLocation( 119 final Location sourceLocation, 120 final ClassPath fileObjCp, 121 final String oppoResourceName, 122 final boolean sourceToTest) { 123 FileObject fileObj = sourceLocation.getFileObject(); 124 FileObject fileObjRoot; 125 126 if ((fileObjRoot = fileObjCp.findOwnerRoot(fileObj)) == null) { 127 return null; 128 } 129 130 URL [] oppoRootsURLs = sourceToTest 131 ? UnitTestForSourceQuery.findUnitTests(fileObjRoot) 132 : UnitTestForSourceQuery.findSources(fileObjRoot); 133 if ((oppoRootsURLs == null) || (oppoRootsURLs.length == 0)) { 137 return null; 138 } 139 140 ClassPath oppoRootsClassPath = ClassPathSupport 141 .createClassPath(oppoRootsURLs); 142 final List <FileObject> oppoFiles = oppoRootsClassPath 143 .findAllResources(oppoResourceName); 144 if (oppoFiles.isEmpty()) { 145 return null; 149 } 150 151 return new Location(oppoFiles.get(0)); 154 156 } 209 210 519 521 private static String getTestResName(String baseResName, String ext) { 522 StringBuilder buf 523 = new StringBuilder (baseResName.length() + ext.length() + 10); 524 buf.append(baseResName).append("Test"); if (ext.length() != 0) { 526 buf.append('.').append(ext); 527 } 528 return buf.toString(); 529 } 530 531 533 private static String getSuiteResName(String baseResName) { 534 if (baseResName.length() == 0) { 535 return JUnitSettings.getDefault().getRootSuiteClassName(); 536 } 537 538 final String suiteSuffix = "Suite"; 540 String lastNamePart 541 = baseResName.substring(baseResName.lastIndexOf('/') + 1); 542 543 StringBuilder buf = new StringBuilder (baseResName.length() 544 + lastNamePart.length() 545 + suiteSuffix.length() 546 + 6); 547 buf.append(baseResName).append('/'); 548 buf.append(Character.toUpperCase(lastNamePart.charAt(0))) 549 .append(lastNamePart.substring(1)); 550 buf.append(suiteSuffix); 551 buf.append(".java"); 553 return buf.toString(); 554 } 555 556 558 private static String getSrcResName(String testResName, String ext) { 559 if (!testResName.endsWith("Test")) { return null; 561 } 562 563 StringBuilder buf 564 = new StringBuilder (testResName.length() + ext.length()); 565 buf.append(testResName.substring(0, testResName.length() - 4)); 566 if (ext.length() != 0) { 567 buf.append('.').append(ext); 568 } 569 return buf.toString(); 570 } 571 572 574 private static String getTestClassName(String baseClassName) { 575 return baseClassName + "Test"; } 577 578 580 private static String getSourceClassName(String testClassName) { 581 final String suffix = "Test"; final int suffixLen = suffix.length(); 583 584 return ((testClassName.length() > suffixLen) 585 && testClassName.endsWith(suffix)) 586 ? testClassName.substring(0, testClassName.length() - suffixLen) 587 : null; 588 } 589 590 592 private static String getTestMethodName(String baseMethodName) { 593 final String prefix = "test"; final int prefixLen = prefix.length(); 595 596 StringBuffer buf = new StringBuffer (prefixLen 597 + baseMethodName.length()); 598 buf.append(prefix).append(baseMethodName); 599 buf.setCharAt(prefixLen, 600 Character.toUpperCase(baseMethodName.charAt(0))); 601 return buf.toString(); 602 } 603 604 606 private static String getSourceMethodName(String testMethodName) { 607 final String prefix = "test"; final int prefixLen = prefix.length(); 609 610 return ((testMethodName.length() > prefixLen) 611 && testMethodName.startsWith(prefix)) 612 ? new StringBuilder (testMethodName.length() - prefixLen) 613 .append(Character.toLowerCase(testMethodName.charAt(prefixLen))) 614 .append(testMethodName.substring(prefixLen + 1)) 615 .toString() 616 : null; 617 } 618 619 628 @Override 629 protected FileObject[] createTests( 630 final FileObject[] filesToTest, 631 final FileObject targetRoot, 632 final Map <CreateTestParam, Object > params) { 633 636 ProgressIndicator progress = new ProgressIndicator(); 637 progress.show(); 638 639 String msg = NbBundle.getMessage( 640 CreateTestAction.class, 641 "MSG_StatusBar_CreateTest_Begin"); progress.displayStatusText(msg); 643 644 final TestCreator testCreator = new TestCreator(params); 645 646 CreationResults results; 647 try { 648 if ((filesToTest == null) || (filesToTest.length == 0)) { 649 651 DataObject doTestTempl = loadTestTemplate( 652 "PROP_emptyTestClassTemplate"); if (doTestTempl == null) { 654 return null; 655 } 656 657 String testClassName = (String ) params.get(CreateTestParam.CLASS_NAME); 658 assert testClassName != null; 659 results = new CreationResults(1); 660 DataObject testDataObj = createEmptyTest(targetRoot, 661 testClassName, 662 testCreator, 663 doTestTempl); 664 if (testDataObj != null) { 665 results.addCreated(testDataObj); 666 } 667 668 } else { 669 DataObject doTestTempl = loadTestTemplate( 670 "PROP_testClassTemplate"); if (doTestTempl == null) { 672 return null; 673 } 674 675 ClassPath testClassPath = ClassPathSupport.createClassPath( 676 new FileObject[] {targetRoot}); 677 678 if ((filesToTest.length == 1) && filesToTest[0].isData()) { 679 String testClassName = (String ) params.get(CreateTestParam.CLASS_NAME); 680 if (testClassName == null) { 681 String srcClassName 682 = ClassPath.getClassPath(filesToTest[0], SOURCE) 683 .getResourceName(filesToTest[0], '.', false); 684 testClassName = getTestClassName(srcClassName); 685 } 686 try { 687 results = createSingleTest( 688 filesToTest[0], 689 testClassName, 690 testCreator, 691 doTestTempl, 692 testClassPath, 693 false, null, progress); 696 } catch (CreationError ex) { 697 ErrorManager.getDefault().notify(ex); 698 results = new CreationResults(1); 699 } 700 } else { 701 DataObject doSuiteTempl = loadTestTemplate( 702 "PROP_testSuiteTemplate"); if (doSuiteTempl == null) { 704 return null; 705 } 706 707 results = new CreationResults(); 708 709 for (FileObject fileToTest : filesToTest) { 711 try { 712 results.combine(createTests(fileToTest, 713 testCreator, 714 doTestTempl, 715 doSuiteTempl, 716 testClassPath, 717 null, 718 progress)); 719 } catch (CreationError e) { 720 ErrorManager.getDefault().notify(e); 721 } 722 } 723 } 724 } 725 } finally { 726 progress.hide(); 727 } 728 729 final Set <SkippedClass> skipped = results.getSkipped(); 730 final Set <DataObject> created = results.getCreated(); 731 if (!skipped.isEmpty()) { 732 String message; 734 if (skipped.size() == 1) { 735 SkippedClass skippedClass = skipped.iterator().next(); 737 738 message = NbBundle.getMessage( 739 DefaultPlugin.class, 740 "MSG_skipped_class", skippedClass.clsName, 742 strReason(skippedClass.reason, "COMMA", "AND")); } else { 744 TestabilityResult reason = TestabilityResult.OK; 747 for (SkippedClass sc : skipped) { 748 reason = TestabilityResult.combine(reason, sc.reason); 749 } 750 751 message = NbBundle.getMessage( 752 DefaultPlugin.class, 753 "MSG_skipped_classes", strReason(reason, "COMMA", "OR")); } 756 TestUtil.notifyUser(message, NotifyDescriptor.INFORMATION_MESSAGE); 757 758 } 759 760 if (created.isEmpty()) { 761 Mutex.EVENT.writeAccess(new Runnable () { 762 public void run() { 763 TestUtil.notifyUser( 764 NbBundle.getMessage( 765 DefaultPlugin.class, 766 "MSG_No_test_created"), NotifyDescriptor.INFORMATION_MESSAGE); 768 } 769 }); 770 } 771 772 FileObject[] createdFiles; 773 if (created.isEmpty()) { 774 createdFiles = null; 775 } else { 776 createdFiles = new FileObject[created.size()]; 777 int i = 0; 778 for (DataObject dObj : created) { 779 createdFiles[i++] = dObj.getPrimaryFile(); 780 } 781 } 782 return createdFiles; 783 } 784 785 796 private DataObject createEmptyTest(FileObject targetRoot, 797 String testClassName, 798 TestCreator testCreator, 799 DataObject templateDataObj) { 800 if (testClassName == null) { 801 throw new IllegalArgumentException ("testClassName = null"); } 803 804 DataObject testDataObj = null; 805 try { 806 DataFolder targetFolderDataObj = DataFolder.findFolder(targetRoot); 807 testDataObj = templateDataObj.createFromTemplate( 808 targetFolderDataObj, testClassName); 809 810 811 FileObject testFileObj = testDataObj.getPrimaryFile(); 812 JavaSource testSrc = JavaSource.forFileObject(testFileObj); 813 testCreator.createEmptyTest(testSrc); 814 } catch (IOException ex) { 815 ErrorManager.getDefault().notify(ex); 816 } 817 return testDataObj; 818 } 819 820 823 private static CreationResults createSingleTest( 824 FileObject sourceFile, 825 String testClassName, 826 final TestCreator testCreator, 827 DataObject templateDataObj, 828 ClassPath testClassPath, 829 boolean skipNonTestable, 830 List <String > parentSuite, 831 ProgressIndicator progress) throws CreationError { 832 833 List <SkippedClass> nonTestable; 834 List <ElementHandle<TypeElement>> testable; 835 try { 836 JavaSource javaSource = JavaSource.forFileObject(sourceFile); 837 if (skipNonTestable) { 838 nonTestable = new ArrayList <SkippedClass>(); 839 testable = TopClassFinder.findTestableTopClasses(javaSource, 840 testCreator, 841 nonTestable); 842 } else { 843 nonTestable = Collections.<SkippedClass>emptyList(); 844 testable = TopClassFinder.findTopClasses(javaSource); 845 } 846 } catch (IOException ex) { 847 throw new CreationError(ex); 848 } 849 850 CreationResults result = new CreationResults(4); 851 if (!nonTestable.isEmpty()) { 852 result.addSkipped(nonTestable); 853 } 854 if (!testable.isEmpty()) { 855 String packageName = TestUtil.getPackageName(ClassPath.getClassPath(sourceFile, ClassPath.SOURCE).getResourceName(sourceFile, '.', false)); 856 857 858 boolean defClassProcessed = false; 859 860 try { 861 for (ElementHandle<TypeElement> clsToTest : testable) { 862 String testResourceName; 863 String srcClassNameShort 864 = TestUtil.getSimpleName(clsToTest.getQualifiedName()); 865 if (testClassName == null) { 866 testResourceName = TestUtil.getTestClassFullName( 867 srcClassNameShort, packageName); 868 testClassName = testResourceName.replace('/', '.'); 869 } else if (!defClassProcessed 870 && srcClassNameShort.equals(sourceFile.getName())) { 871 testResourceName = testClassName.replace('.', '/'); 872 defClassProcessed = true; 873 } else { 874 if (packageName == null) { 875 packageName = TestUtil.getPackageName(testClassName); 876 } 877 testResourceName = TestUtil.getTestClassFullName( 878 srcClassNameShort, packageName); 879 } 880 881 882 DataObject testDataObj = null; 883 FileObject testFile = testClassPath.findResource( 884 testResourceName + ".java"); boolean isNew = (testFile == null); 886 if (testFile == null) { 887 testDataObj = createTestClass(testClassPath, 888 testResourceName, 889 templateDataObj); 890 testFile = testDataObj.getPrimaryFile(); 891 } 892 893 JavaSource testSrc = JavaSource.forFileObject(testFile); 894 testCreator.createSimpleTest(clsToTest, testSrc, isNew); 895 if (testDataObj == null) { 896 testDataObj = DataObject.find(testFile); 897 } 898 save(testDataObj); 899 900 result.addCreated(testDataObj); 901 if (parentSuite != null) { 903 parentSuite.add(testClassName); 904 } 905 } 906 } catch (IOException ex) { throw new CreationError(ex); 908 } 909 } 910 911 return result; 912 } 913 914 917 private static CreationResults createTests( 918 final FileObject srcFileObj, 919 final TestCreator testCreator, 920 DataObject doTestT, 921 DataObject doSuiteT, 922 final ClassPath testClassPath, 923 List <String > parentSuite, 924 ProgressIndicator progress) throws CreationError { 925 926 CreationResults results; 927 if (srcFileObj.isFolder()) { 928 results = new CreationResults(); 929 930 List <String > mySuite = new LinkedList <String >(); 931 932 progress.setMessage(getScanningMsg(srcFileObj.getName()), false); 933 934 for (FileObject childFileObj : srcFileObj.getChildren()) { 935 if (progress.isCanceled()) { 936 results.setAbborted(); 937 break; 938 } 939 results.combine(createTests(childFileObj, 940 testCreator, 941 doTestT, 942 doSuiteT, 943 testClassPath, 944 mySuite, 945 progress)); 946 if (results.isAbborted()) { 947 break; 948 } 949 } 950 951 if (!results.isAbborted() 954 && !mySuite.isEmpty() 955 && JUnitSettings.getDefault().isGenerateSuiteClasses()) { 956 createSuiteTest(srcFileObj, 957 (String ) null, 958 testCreator, 959 doSuiteT, 960 testClassPath, 961 mySuite, 962 parentSuite, 963 progress); 964 } 965 } else if (srcFileObj.isData() && TestUtil.isJavaFile(srcFileObj)) { 966 results = createSingleTest(srcFileObj, 967 (String ) null, testCreator, 969 doTestT, 970 testClassPath, 971 true, 972 parentSuite, 973 progress); 974 } else { 975 results = CreationResults.EMPTY; 976 } 977 return results; 978 } 979 980 983 private static DataObject createSuiteTest( 984 FileObject folder, 985 String suiteName, 986 final TestCreator testCreator, 987 DataObject templateDataObj, 988 ClassPath testClassPath, 989 List <String > classesToInclude, 990 List <String > parentSuite, 991 ProgressIndicator progress) throws CreationError { 992 993 ClassPath cp = ClassPath.getClassPath(folder, SOURCE); 995 assert cp != null : "SOURCE classpath was not found for " + folder; if (cp == null) { 997 return null; 998 } 999 1000 String pkg = cp.getResourceName(folder, '/', false); 1001 String dotPkg = pkg.replace('/', '.'); 1002 String fullSuiteName = (suiteName != null) 1003 ? pkg + '/' + suiteName 1004 : TestUtil.convertPackage2SuiteName(pkg); 1005 1006 try { 1007 1008 DataObject testDataObj = null; 1009 FileObject testFile = testClassPath.findResource( 1010 fullSuiteName + ".java"); boolean isNew = (testFile == null); 1012 if (testFile == null) { 1013 testDataObj = createTestClass(testClassPath, 1014 fullSuiteName, 1015 templateDataObj); 1016 testFile = testDataObj.getPrimaryFile(); 1017 } 1018 1019 List <String > processedClasses; 1020 JavaSource testSrc = JavaSource.forFileObject(testFile); 1021 try { 1022 processedClasses = testCreator.createTestSuite(classesToInclude, 1023 testSrc, 1024 isNew); 1025 if (testDataObj == null) { 1026 testDataObj = DataObject.find(testFile); 1027 } 1028 save(testDataObj); 1029 } catch (Exception ex) { 1030 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex); 1031 return null; 1032 } 1033 1034 if ((parentSuite != null) && !processedClasses.isEmpty()) { 1036 for (String simpleClassName : processedClasses) { 1037 parentSuite.add(dotPkg.length() != 0 1038 ? dotPkg + '.' + simpleClassName 1039 : simpleClassName); 1040 } 1041 } 1042 return testDataObj; 1043 } catch (IOException ioe) { 1044 throw new CreationError(ioe); 1045 } 1046 } 1047 1048 1051 public DataObject createSuiteTest( 1052 final FileObject targetRootFolder, 1053 final FileObject targetFolder, 1054 final String suiteName, 1055 final Map <CreateTestParam, Object > params) { 1056 TestCreator testCreator = new TestCreator(params); 1057 ClassPath testClassPath = ClassPathSupport.createClassPath( 1058 new FileObject[] {targetRootFolder}); 1059 List <String > testClassNames = TestUtil.getJavaFileNames(targetFolder, 1060 testClassPath); 1061 1062 final DataObject doSuiteTempl 1063 = loadTestTemplate("PROP_testSuiteTemplate"); if (doSuiteTempl == null) { 1065 return null; 1066 } 1067 1068 DataObject suiteDataObj; 1069 try { 1070 return createSuiteTest(targetFolder, 1071 suiteName, 1072 testCreator, 1073 doSuiteTempl, 1074 testClassPath, 1075 new LinkedList <String >(testClassNames), 1076 null, null); } catch (CreationError ex) { 1079 return null; 1080 } 1081 } 1082 1083 1085 private static DataObject createTestClass( 1086 ClassPath cp, 1087 String testClassName, 1088 DataObject templateDataObj) throws DataObjectNotFoundException, 1089 IOException { 1090 1091 assert cp.getRoots().length == 1; 1092 FileObject root = cp.getRoots()[0]; 1093 int index = testClassName.lastIndexOf('/'); 1094 String pkg = index > -1 ? testClassName.substring(0, index) 1095 : ""; String clazz = index > -1 ? testClassName.substring(index+1) 1097 : testClassName; 1098 1099 if (pkg.length() > 0) { 1101 root = FileUtil.createFolder(root, pkg); } 1103 return templateDataObj.createFromTemplate( DataFolder.findFolder(root), 1106 clazz); 1107 } 1108 1109 1112 private static void save(DataObject dataObj) throws IOException { 1113 SaveCookie sc = dataObj.getCookie(SaveCookie.class); 1114 if (null != sc) { 1115 sc.save(); 1116 } 1117 } 1118 1119 1127 private static DataObject loadTestTemplate(String templateID) { 1128 String path = NbBundle.getMessage(DefaultPlugin.class, 1130 templateID); 1131 try { 1132 FileObject fo = Repository.getDefault().getDefaultFileSystem() 1133 .findResource(path); 1134 if (fo == null) { 1135 noTemplateMessage(path); 1136 return null; 1137 } 1138 return DataObject.find(fo); 1139 } 1140 catch (DataObjectNotFoundException e) { 1141 noTemplateMessage(path); 1142 return null; 1143 } 1144 } 1145 1146 1149 private static void noTemplateMessage(String temp) { 1150 String msg = NbBundle.getMessage( 1151 CreateTestAction.class, 1152 "MSG_template_not_found", temp); 1154 NotifyDescriptor descr = new NotifyDescriptor.Message( 1155 msg, 1156 NotifyDescriptor.ERROR_MESSAGE); 1157 DialogDisplayer.getDefault().notify(descr); 1158 } 1159 1160 1177 private static String strReason(TestabilityResult reason, String commaKey, String andKey) { 1178 String strComma = NbBundle.getMessage(CreateTestAction.class,commaKey); 1179 String strAnd = NbBundle.getMessage(CreateTestAction.class,andKey); 1180 String strReason = reason.getReason( strComma.substring(1, strComma.length()-1), 1182 strAnd.substring(1, strAnd.length()-1)); 1183 1184 return strReason; 1185 1186 } 1187 1188 1191 private static String getCreatingMsg(String className) { 1192 return NbBundle.getMessage( 1193 DefaultPlugin.class, 1194 "FMT_generator_status_creating", className); 1196 } 1197 1198 1201 private static String getScanningMsg(String sourceName) { 1202 return NbBundle.getMessage( 1203 DefaultPlugin.class, 1204 "FMT_generator_status_scanning", sourceName); 1206 } 1207 1208 1211 private static String getIgnoringMsg(String sourceName, String reason) { 1212 return NbBundle.getMessage( 1213 DefaultPlugin.class, 1214 "FMT_generator_status_ignoring", sourceName); 1216 } 1217 1218 1219 1222 private static final class CreationError extends Exception { 1223 CreationError() {}; 1224 CreationError(Throwable cause) { 1225 super(cause); 1226 } 1227 } 1228 1229 1234 static final class CreationResults { 1235 static final CreationResults EMPTY = new CreationResults(); 1236 1237 Set <DataObject> created; Set <SkippedClass> skipped; 1239 boolean abborted = false; 1240 1241 CreationResults() { this(20);} 1242 1243 CreationResults(int expectedSize) { 1244 created = new HashSet <DataObject>(expectedSize * 2, 0.5f); 1245 skipped = new HashSet <SkippedClass>(expectedSize * 2, 0.5f); 1246 } 1247 1248 void setAbborted() { 1249 abborted = true; 1250 } 1251 1252 1256 boolean isAbborted() { 1257 return abborted; 1258 } 1259 1260 1264 boolean addCreated(DataObject test) { 1265 return created.add(test); 1266 } 1267 1268 1270 boolean addSkipped(SkippedClass skippedClass) { 1271 return skipped.add(skippedClass); 1272 } 1273 1274 1276 void addSkipped(Collection <SkippedClass> skippedClasses) { 1277 if (!skippedClasses.isEmpty()) { 1278 skipped.addAll(skippedClasses); 1279 } 1280 } 1281 1282 1286 Set <SkippedClass> getSkipped() { 1287 return skipped; 1288 } 1289 1290 1294 Set <DataObject> getCreated() { 1295 return created; 1296 } 1297 1298 1304 void combine(CreationResults rhs) { 1305 if (rhs.abborted) { 1306 this.abborted = true; 1307 } 1308 1309 this.created.addAll(rhs.created); 1310 this.skipped.addAll(rhs.skipped); 1311 } 1312 1313 } 1314 1315} | Popular Tags |