Source Code Cross Referenced for DefaultPlugin.java in  » IDE-Netbeans » junit » org » netbeans » modules » junit » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » junit » org.netbeans.modules.junit 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.junit;
0043:
0044:        import java.awt.BorderLayout;
0045:        import java.awt.EventQueue;
0046:        import java.awt.GridLayout;
0047:        import java.awt.event.ActionListener;
0048:        import java.io.IOException;
0049:        import java.net.URL;
0050:        import java.util.ArrayList;
0051:        import java.util.Collection;
0052:        import java.util.Collections;
0053:        import java.util.HashMap;
0054:        import java.util.HashSet;
0055:        import java.util.LinkedList;
0056:        import java.util.List;
0057:        import java.util.Map;
0058:        import java.util.Set;
0059:        import java.util.logging.Logger;
0060:        import java.util.regex.Matcher;
0061:        import java.util.regex.Pattern;
0062:        import javax.lang.model.element.TypeElement;
0063:        import javax.swing.BorderFactory;
0064:        import javax.swing.ButtonGroup;
0065:        import javax.swing.JButton;
0066:        import javax.swing.JComponent;
0067:        import javax.swing.JPanel;
0068:        import javax.swing.JRadioButton;
0069:        import org.netbeans.api.java.classpath.ClassPath;
0070:        import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
0071:        import org.netbeans.api.java.queries.UnitTestForSourceQuery;
0072:        import org.netbeans.api.java.source.ElementHandle;
0073:        import org.netbeans.api.java.source.JavaSource;
0074:        import org.netbeans.api.project.FileOwnerQuery;
0075:        import org.netbeans.api.project.Project;
0076:        import org.netbeans.api.project.ProjectManager;
0077:        import org.netbeans.api.project.ProjectUtils;
0078:        import org.netbeans.api.project.SourceGroup;
0079:        import org.netbeans.api.project.Sources;
0080:        import org.netbeans.api.project.libraries.Library;
0081:        import org.netbeans.api.project.libraries.LibraryManager;
0082:        import org.netbeans.modules.junit.TestabilityResult.SkippedClass;
0083:        import org.netbeans.modules.junit.plugin.JUnitPlugin;
0084:        import org.netbeans.modules.junit.plugin.JUnitPlugin.CreateTestParam;
0085:        import org.netbeans.modules.junit.plugin.JUnitPlugin.Location;
0086:        import org.netbeans.modules.junit.wizards.Utils;
0087:        import org.netbeans.spi.java.classpath.ClassPathProvider;
0088:        import org.netbeans.spi.java.classpath.support.ClassPathSupport;
0089:        import org.openide.DialogDescriptor;
0090:        import org.openide.DialogDisplayer;
0091:        import org.openide.ErrorManager;
0092:        import org.openide.NotifyDescriptor;
0093:        import org.openide.awt.Mnemonics;
0094:        import org.openide.cookies.SaveCookie;
0095:        import org.openide.filesystems.FileObject;
0096:        import org.openide.filesystems.FileUtil;
0097:        import org.openide.filesystems.Repository;
0098:        import org.openide.loaders.DataFolder;
0099:        import org.openide.loaders.DataObject;
0100:        import org.openide.loaders.DataObjectNotFoundException;
0101:        import org.openide.util.HelpCtx;
0102:        import org.openide.util.Mutex;
0103:        import org.openide.util.NbBundle;
0104:        import static java.util.logging.Level.FINER;
0105:        import static java.util.logging.Level.FINEST;
0106:        import static javax.lang.model.util.ElementFilter.methodsIn;
0107:        import static javax.lang.model.util.ElementFilter.typesIn;
0108:        import static org.netbeans.api.java.classpath.ClassPath.SOURCE;
0109:        import static org.netbeans.api.java.classpath.ClassPath.COMPILE;
0110:        import static org.netbeans.api.java.classpath.ClassPath.BOOT;
0111:        import static org.netbeans.api.java.project.JavaProjectConstants.SOURCES_TYPE_JAVA;
0112:        import static org.netbeans.modules.junit.JUnitSettings.JUNIT_GENERATOR_ASK_USER;
0113:        import static org.openide.ErrorManager.ERROR;
0114:        import static org.openide.ErrorManager.WARNING;
0115:        import static org.openide.NotifyDescriptor.CANCEL_OPTION;
0116:        import static org.openide.NotifyDescriptor.OK_CANCEL_OPTION;
0117:        import static org.openide.NotifyDescriptor.QUESTION_MESSAGE;
0118:        import static org.openide.NotifyDescriptor.WARNING_MESSAGE;
0119:
0120:        /**
0121:         * Default JUnit plugin.
0122:         *
0123:         * @author  Marian Petras
0124:         */
0125:        public final class DefaultPlugin extends JUnitPlugin {
0126:
0127:            /** logger for logging management of JUnit libraries */
0128:            private static final Logger LOG_JUNIT_VER = Logger
0129:                    .getLogger(DefaultPlugin.class.getName()
0130:                            + "_JUnit_version_handling"); //NOI18N
0131:
0132:            /** full name of a file specific for the JUnit 3.8.x library */
0133:            private static final String JUNIT3_SPECIFIC = "junit/awtui/TestRunner.class"; //NOI18N
0134:            /** full name of a file specific for the JUnit 4.x library */
0135:            private static final String JUNIT4_SPECIFIC = "org/junit/Test.class"; //NOI18N
0136:
0137:            /** */
0138:            private JUnitVersion junitVer;
0139:
0140:            /** name of FreeMarker template property - generate {@code @BeforeClass} method? */
0141:            private static final String templatePropBeforeClass = "classSetUp"; //NOI18N
0142:            /** name of FreeMarker template property - generate {@code @AfterClass} method? */
0143:            private static final String templatePropAfterClass = "classTearDown";//NOI18N
0144:            /** name of FreeMarker template property - generate {@code @Before} method? */
0145:            private static final String templatePropBefore = "methodSetUp"; //NOI18N
0146:            /** name of FreeMarker template property - generate {@code @After} method? */
0147:            private static final String templatePropAfter = "methodTearDown"; //NOI18N
0148:            /** name of FreeMarker template property - generate in-method source code hints? */
0149:            private static final String templatePropCodeHints = "sourceCodeHint"; //NOI18N
0150:            /** name of FreeMarker template property - generate hints - method placeholders? */
0151:            private static final String templatePropMethodPH = "testMethodsPlaceholder"; //NOI18N
0152:            /** name of FreeMarker template property - use Java annotations? */
0153:            private static final String templatePropUseAnnotations = "useAnnotations"; //NOI18N
0154:            /** name of FreeMarker template property - list of class names */
0155:            private static final String templatePropClassNames = "classNames"; //NOI18N
0156:            /**
0157:             * name of FreeMarker template property - list of class names,
0158:             * each with a suffix <code>&quot;.class&quot;</code>
0159:             */
0160:            private static final String templatePropClasses = "classes"; //NOI18N
0161:
0162:            /** */
0163:            private static java.util.ResourceBundle bundle = org.openide.util.NbBundle
0164:                    .getBundle(DefaultPlugin.class);
0165:
0166:            /**
0167:             * 
0168:             */
0169:            @Override
0170:            protected boolean canCreateTests(FileObject... fileObjects) {
0171:                if (fileObjects.length == 0) {
0172:                    return false;
0173:                }
0174:
0175:                final FileObject firstFile = fileObjects[0];
0176:                final SourceGroup sourceGroup = findSourceGroup(firstFile);
0177:                if (sourceGroup == null) {
0178:                    return false;
0179:                }
0180:                final FileObject rootFolder = sourceGroup.getRootFolder();
0181:                if (UnitTestForSourceQuery.findUnitTests(rootFolder).length == 0) {
0182:                    return false;
0183:                }
0184:
0185:                /*
0186:                 * Now we know that source folder of the first file has a corresponding
0187:                 * test folder (possible non-existent).
0188:                 */
0189:                if (fileObjects.length == 1) {
0190:                    /* ... if there is just one file selected, it is all we need: */
0191:                    return true;
0192:                }
0193:
0194:                /*
0195:                 * ...for multiple files, we just check that all the selected files
0196:                 * have the same root folder:
0197:                 */
0198:                for (int i = 1; i < fileObjects.length; i++) {
0199:                    FileObject fileObj = fileObjects[i];
0200:                    if (!FileUtil.isParentOf(rootFolder, fileObj)
0201:                            || !sourceGroup.contains(fileObj)) {
0202:                        return false;
0203:                    }
0204:                }
0205:                return true;
0206:            }
0207:
0208:            /**
0209:             * Finds a Java source group the given file belongs to.
0210:             * 
0211:             * @param  file  {@code FileObject} to find a {@code SourceGroup} for
0212:             * @return  the found {@code SourceGroup}, or {@code null} if the given
0213:             *          file does not belong to any Java source group
0214:             */
0215:            private static SourceGroup findSourceGroup(FileObject file) {
0216:                final Project project = FileOwnerQuery.getOwner(file);
0217:                if (project == null) {
0218:                    return null;
0219:                }
0220:
0221:                Sources src = ProjectUtils.getSources(project);
0222:                SourceGroup[] srcGrps = src.getSourceGroups(SOURCES_TYPE_JAVA);
0223:                for (SourceGroup srcGrp : srcGrps) {
0224:                    FileObject rootFolder = srcGrp.getRootFolder();
0225:                    if (((file == rootFolder) || FileUtil.isParentOf(
0226:                            rootFolder, file))
0227:                            && srcGrp.contains(file)) {
0228:                        return srcGrp;
0229:                    }
0230:                }
0231:                return null;
0232:            }
0233:
0234:            /**
0235:             *
0236:             */
0237:            protected Location getTestLocation(Location sourceLocation) {
0238:                FileObject fileObj = sourceLocation.getFileObject();
0239:                ClassPath srcCp;
0240:
0241:                if ((srcCp = ClassPath.getClassPath(fileObj, SOURCE)) == null) {
0242:                    return null;
0243:                }
0244:
0245:                String baseResName = srcCp.getResourceName(fileObj, '/', false);
0246:                String testResName = !fileObj.isFolder() ? getTestResName(
0247:                        baseResName, fileObj.getExt())
0248:                        : getSuiteResName(baseResName);
0249:                assert testResName != null;
0250:
0251:                return getOppositeLocation(sourceLocation, srcCp, testResName,
0252:                        true);
0253:            }
0254:
0255:            /**
0256:             *
0257:             */
0258:            protected Location getTestedLocation(Location testLocation) {
0259:                FileObject fileObj = testLocation.getFileObject();
0260:                ClassPath srcCp;
0261:
0262:                if (fileObj.isFolder()
0263:                        || ((srcCp = ClassPath.getClassPath(fileObj, SOURCE)) == null)) {
0264:                    return null;
0265:                }
0266:
0267:                String baseResName = srcCp.getResourceName(fileObj, '/', false);
0268:                String srcResName = getSrcResName(baseResName, fileObj.getExt());
0269:                if (srcResName == null) {
0270:                    return null; //if the selectedFO is not a test class (by name)
0271:                }
0272:
0273:                return getOppositeLocation(testLocation, srcCp, srcResName,
0274:                        false);
0275:            }
0276:
0277:            /**
0278:             *
0279:             */
0280:            private static Location getOppositeLocation(
0281:                    final Location sourceLocation, final ClassPath fileObjCp,
0282:                    final String oppoResourceName, final boolean sourceToTest) {
0283:                FileObject fileObj = sourceLocation.getFileObject();
0284:                FileObject fileObjRoot;
0285:
0286:                if ((fileObjRoot = fileObjCp.findOwnerRoot(fileObj)) == null) {
0287:                    return null;
0288:                }
0289:
0290:                URL[] oppoRootsURLs = sourceToTest ? UnitTestForSourceQuery
0291:                        .findUnitTests(fileObjRoot) : UnitTestForSourceQuery
0292:                        .findSources(fileObjRoot);
0293:                //if (sourceToTest && (oppoRootsURLs.length == 0)) {
0294:                //    PENDING - offer creation of new unit tests root
0295:                //}
0296:                if ((oppoRootsURLs == null) || (oppoRootsURLs.length == 0)) {
0297:                    return null;
0298:                }
0299:
0300:                ClassPath oppoRootsClassPath = ClassPathSupport
0301:                        .createClassPath(oppoRootsURLs);
0302:                final List<FileObject> oppoFiles = oppoRootsClassPath
0303:                        .findAllResources(oppoResourceName);
0304:                if (oppoFiles.isEmpty()) {
0305:                    //if (sourceToTest) {
0306:                    //    PENDING - offer creation of new test class
0307:                    //}
0308:                    return null;
0309:                }
0310:
0311:                //        final ElementHandle elementHandle = sourceLocation.getElementHandle();
0312:                //        if (elementHandle == null) {
0313:                return new Location(oppoFiles.get(0)/*, null*/);
0314:                //        }
0315:
0316:                //        /* Build SOURCE classpath: */
0317:                //        ClassPath[] srcCpDelegates = new ClassPath[2];
0318:                //        if (sourceToTest) {
0319:                //            srcCpDelegates[0] = fileObjCp;
0320:                //            srcCpDelegates[1] = oppoRootsClassPath;
0321:                //        } else {
0322:                //            srcCpDelegates[0] = oppoRootsClassPath;
0323:                //            srcCpDelegates[1] = fileObjCp;
0324:                //        }
0325:                //        ClassPath srcClassPath
0326:                //                = ClassPathSupport.createProxyClassPath(srcCpDelegates);
0327:                //        
0328:                //        /* Build COMPILE classpath: */
0329:                //        FileObject[] oppoRoots = oppoRootsClassPath.getRoots();
0330:                //        ClassPath[] compCpDelegates = new ClassPath[oppoRoots.length + 1];
0331:                //        int delegateIndex = 0;
0332:                //        if (sourceToTest) {
0333:                //            compCpDelegates[delegateIndex++]
0334:                //                    = ClassPath.getClassPath(fileObjRoot, COMPILE);
0335:                //        }
0336:                //        for (FileObject oppoRoot : oppoRoots) {
0337:                //            compCpDelegates[delegateIndex++]
0338:                //                    = ClassPath.getClassPath(oppoRoot, COMPILE);
0339:                //        }
0340:                //        if (!sourceToTest) {
0341:                //            compCpDelegates[delegateIndex++]
0342:                //                    = ClassPath.getClassPath(fileObjRoot, COMPILE);
0343:                //        }
0344:                //        ClassPath compClassPath
0345:                //                = ClassPathSupport.createProxyClassPath(compCpDelegates);
0346:                //        
0347:                //        /* Obtain the BOOT classpath: */
0348:                //        ClassPath bootClassPath = ClassPath.getClassPath(fileObj, BOOT);
0349:                //        
0350:                //        ClasspathInfo cpInfo = ClasspathInfo.create(bootClassPath,
0351:                //                                                    compClassPath,
0352:                //                                                    srcClassPath);
0353:                //        List<FileObject> files = new ArrayList<FileObject>(oppoFiles.size() + 1);
0354:                //        files.add(fileObj);
0355:                //        files.addAll(oppoFiles);
0356:                //        JavaSource javaSource = JavaSource.create(cpInfo, files);
0357:                //        
0358:                //        try {
0359:                //            MatchFinder matchFinder = new MatchFinder(sourceLocation,
0360:                //                                                      oppoFiles,
0361:                //                                                      sourceToTest);
0362:                //            javaSource.runUserActionTask(matchFinder, true);
0363:                //            return matchFinder.getResult();
0364:                //        } catch (IOException ex) {
0365:                //            Logger.getLogger("global").log(Level.SEVERE, null, ex);     //NOI18N
0366:                //            return null;
0367:                //        }
0368:            }
0369:
0370:            //    /**
0371:            //     *
0372:            //     */
0373:            //    private static final class MatchFinder
0374:            //                            implements CancellableTask<CompilationController> {
0375:            //        private final FileObject currFile;
0376:            //        private final ElementHandle currElemHandle;
0377:            //        private final List<FileObject> oppoFiles;
0378:            //        private final boolean sourceToTest;
0379:            //        
0380:            //        private String currFilePkgPrefix;
0381:            //        private Element currElement;
0382:            //        
0383:            //        private volatile boolean cancelled;
0384:            //        
0385:            //        private String[] oppoClassNames;
0386:            //        private String oppoMethodName;
0387:            //        private int bestCandidateClassNamesCount;
0388:            //        private FileObject bestCandidateFile;
0389:            //        private Element bestCandidateElement;
0390:            //        
0391:            //        /** */
0392:            //        private FileObject oppoFile = null;
0393:            //        /** storage for the result */
0394:            //        private Element oppoElement = null;
0395:            //        
0396:            //        /**
0397:            //         *
0398:            //         */
0399:            //        private MatchFinder(Location currLocation,
0400:            //                            List<FileObject> oppoFiles,
0401:            //                            boolean sourceToTest) {
0402:            //            this.currFile = currLocation.getFileObject();
0403:            //            this.currElemHandle = currLocation.getElementHandle();
0404:            //            this.oppoFiles = oppoFiles;
0405:            //            this.sourceToTest = sourceToTest;
0406:            //        }
0407:            //        
0408:            //        /**
0409:            //         * This method is run once for the file referred by
0410:            //         * {@link #currLocation} and then once for each file contained
0411:            //         * in {@link #oppoFiles}.
0412:            //         *
0413:            //         * @param  controller  controller for the current run of this method
0414:            //         */
0415:            //        public void run(CompilationController controller) throws IOException {
0416:            //            if (oppoFile != null) {
0417:            //                /* We already have the result. */
0418:            //                
0419:            //                /*
0420:            //                 * This should be only possible if there are multiple oppoFiles.
0421:            //                 */
0422:            //                assert oppoFiles.size() > 1;
0423:            //                return;
0424:            //            }
0425:            //            
0426:            //            final FileObject runFile = controller.getFileObject();
0427:            //            if (runFile == currFile) {
0428:            //                resolveCurrentElement(controller);   //--> currElement
0429:            //                return;
0430:            //            }
0431:            //            
0432:            //            if (currElement == null) {
0433:            //                /*
0434:            //                 * The element for 'currLocation' was not resolved during
0435:            //                 * the first run of this method on this instance.
0436:            //                 */
0437:            //                return;
0438:            //            }
0439:            //            if ((oppoClassNames == null) || (oppoClassNames.length == 0)) {
0440:            //                return;
0441:            //            }
0442:            //
0443:            //            controller.toPhase(Phase.PARSED);
0444:            //            
0445:            //            final Elements elements = controller.getElements();
0446:            //            TypeElement topClass = elements.getTypeElement(getCanonicalClassName(oppoClassNames[0]));
0447:            //            if ((topClass != null)
0448:            //                    && !CLASS_LIKE_ELEM_TYPES.contains(topClass.getKind())) {
0449:            //                topClass = null;
0450:            //            }
0451:            //            if (cancelled || (topClass == null)) {
0452:            //                return;
0453:            //            }
0454:            //            
0455:            //            int classNamesCount = 0;
0456:            //            TypeElement bestClass = null;
0457:            //            TypeElement theSubClass = topClass;
0458:            //            while ((theSubClass != null) && (++classNamesCount < oppoClassNames.length)) {
0459:            //                bestClass = theSubClass;
0460:            //                
0461:            //                String oppoClassName = oppoClassNames[classNamesCount];
0462:            //                if (oppoClassName == null) {
0463:            //                    break;
0464:            //                }
0465:            //                
0466:            //                theSubClass = null;
0467:            //                for (TypeElement subClass : typesIn(bestClass.getEnclosedElements())) {
0468:            //                    if (cancelled) {
0469:            //                        return;
0470:            //                    }
0471:            //                    
0472:            //                    if (CLASS_LIKE_ELEM_TYPES.contains(subClass.getKind())
0473:            //                            && subClass.getSimpleName().toString().equals(oppoClassName)) {
0474:            //                        theSubClass = subClass;
0475:            //                        break;
0476:            //                    }
0477:            //                }
0478:            //            }
0479:            //            if (cancelled) {
0480:            //                return;
0481:            //            }
0482:            //            if (classNamesCount == oppoClassNames.length) {
0483:            //                bestClass = theSubClass;  //this does not get called in the above while (...) cycle
0484:            //                
0485:            //                if (oppoMethodName == null) {
0486:            //                    oppoFile = runFile;
0487:            //                    oppoElement = bestClass;
0488:            //                } else {
0489:            //                    ExecutableElement testMethod = findOppoMethod(bestClass);
0490:            //                    if (testMethod != null) {
0491:            //                        /* We found the test method! */
0492:            //                        oppoFile = runFile;
0493:            //                        oppoElement = testMethod;
0494:            //                    }
0495:            //                }
0496:            //                if (oppoFile != null) {
0497:            //                    return;
0498:            //                }
0499:            //            }
0500:            //            
0501:            //            if (classNamesCount > bestCandidateClassNamesCount) {
0502:            //                bestCandidateFile = runFile;
0503:            //                bestCandidateElement = bestClass;
0504:            //                bestCandidateClassNamesCount = classNamesCount;
0505:            //            }
0506:            //        }
0507:            //        
0508:            //        /**
0509:            //         */
0510:            //        private ExecutableElement findOppoMethod(TypeElement classElem) {
0511:            //            for (ExecutableElement elem : methodsIn(classElem.getEnclosedElements())) {
0512:            //                if (elem.getSimpleName().toString().equals(oppoMethodName)) {
0513:            //                    if (!sourceToTest) {
0514:            //                        return elem;
0515:            //                    }
0516:            //                    if (elem.getParameters().isEmpty()) {
0517:            //                        Set<Modifier> modifiers = elem.getModifiers();
0518:            //                        if (modifiers.contains(Modifier.PUBLIC)
0519:            //                                && !modifiers.contains(Modifier.STATIC)) {
0520:            //                            return elem;
0521:            //                        }
0522:            //                    }
0523:            //                    break;
0524:            //                }
0525:            //            }
0526:            //            return null;
0527:            //        }
0528:            //
0529:            //        public void cancel() {
0530:            //            cancelled = true;
0531:            //        }
0532:            //        
0533:            //        /**
0534:            //         */
0535:            //        private Location getResult() {
0536:            //            assert (oppoFile == null) == (oppoElement == null);
0537:            //            
0538:            //            return (oppoFile != null)
0539:            //                   ? new Location(oppoFile, oppoElement)
0540:            //                   : new Location(bestCandidateFile, bestCandidateElement);
0541:            //        }
0542:            //        
0543:            //        /**
0544:            //         * Resolves 'currElementHandle' and stores the result to 'currElement'.
0545:            //         */
0546:            //        private void resolveCurrentElement(CompilationController controller)
0547:            //                                                            throws IOException {
0548:            //            String canonicalFileName
0549:            //                   = controller.getClasspathInfo().getClassPath(PathKind.SOURCE)
0550:            //                     .getResourceName(currFile, '.', false);
0551:            //            int lastDotIndex = canonicalFileName.lastIndexOf('.');
0552:            //            currFilePkgPrefix = (lastDotIndex != -1)
0553:            //                                ? canonicalFileName.substring(0, lastDotIndex + 1)
0554:            //                                : null;
0555:            //            
0556:            //            controller.toPhase(Phase.PARSED);
0557:            //            if (cancelled) {
0558:            //                return;
0559:            //            }
0560:            //            currElement = currElemHandle.resolve(controller);
0561:            //            if (currElement == null) {
0562:            //                Logger.getLogger(getClass().getName()).log(
0563:            //                        Level.INFO,
0564:            //                        "Could not resolve element " + currElemHandle); //NOI18N
0565:            //                return;
0566:            //            }
0567:            //            
0568:            //            if (cancelled) {
0569:            //                return;
0570:            //            }
0571:            //            
0572:            //            Element clsElement;
0573:            //            ElementKind currElemKind = currElement.getKind();
0574:            //            if (CLASS_LIKE_ELEM_TYPES.contains(currElement.getKind())) {
0575:            //                clsElement = currElement;
0576:            //                oppoMethodName = null;
0577:            //            } else {
0578:            //                clsElement = currElement.getEnclosingElement();
0579:            //                oppoMethodName = (currElemKind == ElementKind.METHOD)
0580:            //                     ? getOppoMethodName(currElement.getSimpleName().toString())
0581:            //                     : null;    //no rule for finding tests for initializers
0582:            //            }
0583:            //            assert CLASS_LIKE_ELEM_TYPES.contains(clsElement.getKind());
0584:            //            
0585:            //            if (cancelled) {
0586:            //                return;
0587:            //            }
0588:            //            
0589:            //            oppoClassNames = buildOppoClassNames(clsElement);
0590:            //            if (oppoClassNames == null) {
0591:            //                oppoMethodName = null;
0592:            //            } else {
0593:            //                for (int i = 0; i < oppoClassNames.length; i++) {
0594:            //                    if (oppoClassNames[i] == null) {
0595:            //                        if (i == 0) {
0596:            //                            oppoClassNames = null;
0597:            //                        } else {
0598:            //                            String[] newArray = new String[i];
0599:            //                            System.arraycopy(oppoClassNames, 0, newArray, 0, i);
0600:            //                            oppoClassNames = newArray;
0601:            //                        }
0602:            //                        oppoMethodName = null;
0603:            //                        break;
0604:            //                    }
0605:            //                }
0606:            //
0607:            //            }
0608:            //        }
0609:            //        
0610:            //        /**
0611:            //         * 
0612:            //         * @return  may return {@code null} if this task has been cancelled
0613:            //         */
0614:            //        private String[] buildOppoClassNames(Element clsElement) {
0615:            //            String[] oppoClsNames;
0616:            //            String oppoClsName;
0617:            //            
0618:            //            Element clsParent = clsElement.getEnclosingElement();
0619:            //            if ((clsParent == null)
0620:            //                    || !CLASS_LIKE_ELEM_TYPES.contains(clsParent.getKind())) {
0621:            //                oppoClsName = getOppoClassName(clsElement.getSimpleName().toString());
0622:            //                oppoClsNames = (oppoClsName != null)
0623:            //                               ? new String[] {oppoClsName}
0624:            //                               : null;
0625:            //            } else {
0626:            //                List<String> clsNames = new ArrayList<String>();
0627:            //                clsNames.add(clsElement.getSimpleName().toString());
0628:            //                do {
0629:            //                    if (cancelled) {
0630:            //                        return null;
0631:            //                    }
0632:            //                    
0633:            //                    clsNames.add(clsParent.getSimpleName().toString());
0634:            //                    clsParent = clsParent.getEnclosingElement();
0635:            //                } while ((clsParent != null)
0636:            //                        && CLASS_LIKE_ELEM_TYPES.contains(clsParent.getKind()));
0637:            //                
0638:            //                if (cancelled) {
0639:            //                    return null;
0640:            //                }
0641:            //                
0642:            //                final int size = clsNames.size();
0643:            //                oppoClsNames = new String[size];
0644:            //                for (int i = 0; i < size; i++) {
0645:            //                    oppoClsName = getOppoClassName(clsNames.get(size - i - 1));
0646:            //                    if (oppoClsName == null) {
0647:            //                        break;
0648:            //                    }
0649:            //                    oppoClsNames[i] = oppoClsName;
0650:            //                }
0651:            //            }
0652:            //            return oppoClsNames;
0653:            //        }
0654:            //        
0655:            //        /**
0656:            //         */
0657:            //        private String getCanonicalClassName(String shortClassName) {
0658:            //            return (currFilePkgPrefix != null)
0659:            //                   ? currFilePkgPrefix + shortClassName
0660:            //                   : shortClassName;
0661:            //        }
0662:            //        
0663:            //        /**
0664:            //         */
0665:            //        private String getOppoClassName(String name) {
0666:            //            return sourceToTest ? getTestClassName(name)
0667:            //                                : getSourceClassName(name);
0668:            //        }
0669:            //        
0670:            //        /**
0671:            //         */
0672:            //        private String getOppoMethodName(String name) {
0673:            //            return sourceToTest ? getTestMethodName(name)
0674:            //                                : getSourceMethodName(name);
0675:            //        }
0676:            //        
0677:            //    }
0678:
0679:            /**
0680:             */
0681:            private static String getTestResName(String baseResName, String ext) {
0682:                StringBuilder buf = new StringBuilder(baseResName.length()
0683:                        + ext.length() + 10);
0684:                buf.append(baseResName).append("Test"); //NOI18N
0685:                if (ext.length() != 0) {
0686:                    buf.append('.').append(ext);
0687:                }
0688:                return buf.toString();
0689:            }
0690:
0691:            /**
0692:             */
0693:            private static String getSuiteResName(String baseResName) {
0694:                if (baseResName.length() == 0) {
0695:                    return JUnitSettings.getDefault().getRootSuiteClassName();
0696:                }
0697:
0698:                final String suiteSuffix = "Suite"; //NOI18N
0699:
0700:                String lastNamePart = baseResName.substring(baseResName
0701:                        .lastIndexOf('/') + 1);
0702:
0703:                StringBuilder buf = new StringBuilder(baseResName.length()
0704:                        + lastNamePart.length() + suiteSuffix.length() + 6);
0705:                buf.append(baseResName).append('/');
0706:                buf.append(Character.toUpperCase(lastNamePart.charAt(0)))
0707:                        .append(lastNamePart.substring(1));
0708:                buf.append(suiteSuffix);
0709:                buf.append(".java"); //NOI18N
0710:
0711:                return buf.toString();
0712:            }
0713:
0714:            /**
0715:             */
0716:            private static String getSrcResName(String testResName, String ext) {
0717:                if (!testResName.endsWith("Test")) { //NOI18N
0718:                    return null;
0719:                }
0720:
0721:                StringBuilder buf = new StringBuilder(testResName.length()
0722:                        + ext.length());
0723:                buf.append(testResName.substring(0, testResName.length() - 4));
0724:                if (ext.length() != 0) {
0725:                    buf.append('.').append(ext);
0726:                }
0727:                return buf.toString();
0728:            }
0729:
0730:            /**
0731:             */
0732:            private static String getTestClassName(String baseClassName) {
0733:                return baseClassName + "Test"; //NOI18N
0734:            }
0735:
0736:            /**
0737:             */
0738:            private static String getSourceClassName(String testClassName) {
0739:                final String suffix = "Test"; //NOI18N
0740:                final int suffixLen = suffix.length();
0741:
0742:                return ((testClassName.length() > suffixLen) && testClassName
0743:                        .endsWith(suffix)) ? testClassName.substring(0,
0744:                        testClassName.length() - suffixLen) : null;
0745:            }
0746:
0747:            /**
0748:             */
0749:            private static String getTestMethodName(String baseMethodName) {
0750:                final String prefix = "test"; //NOI18N
0751:                final int prefixLen = prefix.length();
0752:
0753:                StringBuffer buf = new StringBuffer(prefixLen
0754:                        + baseMethodName.length());
0755:                buf.append(prefix).append(baseMethodName);
0756:                buf.setCharAt(prefixLen, Character.toUpperCase(baseMethodName
0757:                        .charAt(0)));
0758:                return buf.toString();
0759:            }
0760:
0761:            /**
0762:             */
0763:            private static String getSourceMethodName(String testMethodName) {
0764:                final String prefix = "test"; //NOI18N
0765:                final int prefixLen = prefix.length();
0766:
0767:                return ((testMethodName.length() > prefixLen) && testMethodName
0768:                        .startsWith(prefix)) ? new StringBuilder(testMethodName
0769:                        .length()
0770:                        - prefixLen)
0771:                        .append(
0772:                                Character.toLowerCase(testMethodName
0773:                                        .charAt(prefixLen))).append(
0774:                                testMethodName.substring(prefixLen + 1))
0775:                        .toString() : null;
0776:            }
0777:
0778:            /**
0779:             * Creates test classes for given source classes.
0780:             * 
0781:             * @param filesToTest  source files for which test classes should be
0782:             *                      created
0783:             * @param targetRoot   root folder of the target source root
0784:             * @param params  parameters of creating test class
0785:             * @return created test files
0786:             */
0787:            @Override
0788:            protected FileObject[] createTests(final FileObject[] filesToTest,
0789:                    final FileObject targetRoot,
0790:                    final Map<CreateTestParam, Object> params) {
0791:                //XXX: not documented that in case that if filesToTest is <null>,
0792:                //the target root param works as a target folder
0793:
0794:                ProgressIndicator progress = new ProgressIndicator();
0795:                progress.show();
0796:
0797:                String msg = NbBundle.getMessage(CreateTestAction.class,
0798:                        "MSG_StatusBar_CreateTest_Begin"); //NOI18N
0799:                progress.displayStatusText(msg);
0800:
0801:                final TestCreator testCreator = new TestCreator(params,
0802:                        junitVer);
0803:
0804:                CreationResults results;
0805:                try {
0806:                    final String templateId;
0807:                    final String suiteTemplateId;
0808:                    boolean forTestSuite = (filesToTest != null)
0809:                            && (filesToTest.length != 0)
0810:                            && ((filesToTest.length > 1) || !filesToTest[0]
0811:                                    .isData());
0812:                    final boolean useAnnotations;
0813:                    switch (junitVer) {
0814:                    case JUNIT3:
0815:                        templateId = "PROP_junit3_testClassTemplate"; //NOI18N
0816:                        suiteTemplateId = forTestSuite ? "PROP_junit3_testSuiteTemplate" //NOI18N
0817:                                : null;
0818:                        useAnnotations = TestUtil
0819:                                .areAnnotationsSupported(targetRoot);
0820:                        break;
0821:                    case JUNIT4:
0822:                        templateId = "PROP_junit4_testClassTemplate"; //NOI18N
0823:                        suiteTemplateId = forTestSuite ? "PROP_junit4_testSuiteTemplate" //NOI18N
0824:                                : null;
0825:                        useAnnotations = true;
0826:                        break;
0827:                    default:
0828:                        assert false;
0829:                        templateId = null;
0830:                        suiteTemplateId = null;
0831:                        useAnnotations = false;
0832:                        break;
0833:                    }
0834:                    DataObject doTestTempl = (templateId != null) ? loadTestTemplate(templateId)
0835:                            : null;
0836:                    if (doTestTempl == null) {
0837:                        return null;
0838:                    }
0839:                    DataObject doSuiteTempl = (suiteTemplateId != null) ? loadTestTemplate(suiteTemplateId)
0840:                            : null;
0841:                    if (forTestSuite && (doSuiteTempl == null)) {
0842:                        return null;
0843:                    }
0844:
0845:                    Map<String, Boolean> templateParams = createTemplateParams(params);
0846:                    if (useAnnotations) {
0847:                        templateParams.put(templatePropUseAnnotations,
0848:                                useAnnotations);
0849:                    }
0850:
0851:                    if ((filesToTest == null) || (filesToTest.length == 0)) {
0852:                        //XXX: Not documented that filesToTest may be <null>
0853:
0854:                        addTemplateParamEntry(params,
0855:                                CreateTestParam.INC_CODE_HINT, templateParams,
0856:                                templatePropMethodPH);
0857:
0858:                        String testClassName = (String) params
0859:                                .get(CreateTestParam.CLASS_NAME);
0860:                        assert testClassName != null;
0861:                        results = new CreationResults(1);
0862:                        DataObject testDataObj = createEmptyTest(targetRoot,
0863:                                testClassName, testCreator, templateParams,
0864:                                doTestTempl);
0865:                        if (testDataObj != null) {
0866:                            results.addCreated(testDataObj);
0867:                        }
0868:
0869:                    } else {
0870:                        ClassPath testClassPath = ClassPathSupport
0871:                                .createClassPath(new FileObject[] { targetRoot });
0872:                        if (!forTestSuite) {
0873:                            String testClassName = (String) params
0874:                                    .get(CreateTestParam.CLASS_NAME);
0875:                            if (testClassName == null) {
0876:                                String srcClassName = ClassPath.getClassPath(
0877:                                        filesToTest[0], SOURCE)
0878:                                        .getResourceName(filesToTest[0], '.',
0879:                                                false);
0880:                                testClassName = getTestClassName(srcClassName);
0881:                            }
0882:                            try {
0883:                                results = createSingleTest(filesToTest[0],
0884:                                        testClassName, testCreator,
0885:                                        templateParams, doTestTempl,
0886:                                        testClassPath, false, //do not skip any classes
0887:                                        null, //parent suite
0888:                                        progress);
0889:                            } catch (CreationError ex) {
0890:                                ErrorManager.getDefault().notify(ex);
0891:                                results = new CreationResults(1);
0892:                            }
0893:                        } else {
0894:                            results = new CreationResults();
0895:
0896:                            // go through all nodes
0897:                            for (FileObject fileToTest : filesToTest) {
0898:                                try {
0899:                                    results.combine(createTests(fileToTest,
0900:                                            testCreator, templateParams,
0901:                                            doTestTempl, doSuiteTempl,
0902:                                            testClassPath, null, progress));
0903:                                } catch (CreationError e) {
0904:                                    ErrorManager.getDefault().notify(e);
0905:                                }
0906:                            }
0907:                        }
0908:                    }
0909:                } finally {
0910:                    progress.hide();
0911:                }
0912:
0913:                final Set<SkippedClass> skipped = results.getSkipped();
0914:                final Set<DataObject> created = results.getCreated();
0915:                if (!skipped.isEmpty()) {
0916:                    // something was skipped
0917:                    String message;
0918:                    if (skipped.size() == 1) {
0919:                        // one class? report it
0920:                        SkippedClass skippedClass = skipped.iterator().next();
0921:
0922:                        message = NbBundle.getMessage(DefaultPlugin.class,
0923:                                "MSG_skipped_class", //NOI18N
0924:                                skippedClass.clsName, strReason(
0925:                                        skippedClass.reason, "COMMA", "AND"));//NOI18N
0926:                    } else {
0927:                        // more classes, report a general error
0928:                        // combine the results
0929:                        TestabilityResult reason = TestabilityResult.OK;
0930:                        for (SkippedClass sc : skipped) {
0931:                            reason = TestabilityResult.combine(reason,
0932:                                    sc.reason);
0933:                        }
0934:
0935:                        message = NbBundle.getMessage(DefaultPlugin.class,
0936:                                "MSG_skipped_classes", //NOI18N
0937:                                strReason(reason, "COMMA", "OR")); //NOI18N
0938:                    }
0939:                    TestUtil.notifyUser(message,
0940:                            NotifyDescriptor.INFORMATION_MESSAGE);
0941:
0942:                }
0943:
0944:                if (created.isEmpty()) {
0945:                    Mutex.EVENT.writeAccess(new Runnable() {
0946:                        public void run() {
0947:                            TestUtil.notifyUser(
0948:                                    NbBundle.getMessage(DefaultPlugin.class,
0949:                                            "MSG_No_test_created"), //NOI18N
0950:                                    NotifyDescriptor.INFORMATION_MESSAGE);
0951:                        }
0952:                    });
0953:                }
0954:
0955:                FileObject[] createdFiles;
0956:                if (created.isEmpty()) {
0957:                    createdFiles = new FileObject[0];
0958:                } else {
0959:                    createdFiles = new FileObject[created.size()];
0960:                    int i = 0;
0961:                    for (DataObject dObj : created) {
0962:                        createdFiles[i++] = dObj.getPrimaryFile();
0963:                    }
0964:                }
0965:                return createdFiles;
0966:            }
0967:
0968:            /**
0969:             * Create a map of FreeMaker template parameters from a map
0970:             * of {@code CreateTestParam}s.
0971:             */
0972:            public static final Map<String, Boolean> createTemplateParams(
0973:                    Map<CreateTestParam, Object> params) {
0974:                Map<String, Boolean> result = new HashMap<String, Boolean>(7);
0975:
0976:                addTemplateParamEntry(params, CreateTestParam.INC_CLASS_SETUP,
0977:                        result, templatePropBeforeClass);
0978:                addTemplateParamEntry(params,
0979:                        CreateTestParam.INC_CLASS_TEAR_DOWN, result,
0980:                        templatePropAfterClass);
0981:                addTemplateParamEntry(params, CreateTestParam.INC_SETUP,
0982:                        result, templatePropBefore);
0983:                addTemplateParamEntry(params, CreateTestParam.INC_TEAR_DOWN,
0984:                        result, templatePropAfter);
0985:                addTemplateParamEntry(params, CreateTestParam.INC_CODE_HINT,
0986:                        result, templatePropCodeHints);
0987:
0988:                return result;
0989:            }
0990:
0991:            private static void addTemplateParamEntry(
0992:                    Map<CreateTestParam, Object> srcParams,
0993:                    CreateTestParam srcParamKey,
0994:                    Map<String, Boolean> templParams, String templParamKey) {
0995:                Object value = srcParams.get(srcParamKey);
0996:                if (value instanceof  Boolean) {
0997:                    templParams.put(templParamKey, Boolean.class.cast(value));
0998:                }
0999:            }
1000:
1001:            /**
1002:             */
1003:            public boolean setupJUnitVersionByProject(FileObject targetFolder) {
1004:                return createTestActionCalled(new FileObject[] { targetFolder });
1005:            }
1006:
1007:            /**
1008:             */
1009:            @Override
1010:            protected boolean createTestActionCalled(FileObject[] selectedFiles) {
1011:                assert EventQueue.isDispatchThread();
1012:
1013:                LOG_JUNIT_VER.finer("createTestActionCalled(...)"); //NOI18N
1014:
1015:                Project project = FileOwnerQuery.getOwner(selectedFiles[0]);
1016:                assert project != null; //PENDING
1017:
1018:                boolean storeSettings;
1019:                try {
1020:                    storeSettings = readProjectSettingsJUnitVer(project);
1021:                    if (!storeSettings) {
1022:                        LOG_JUNIT_VER
1023:                                .finest(" - will not be able to store JUnit version settings"); //NOI18N
1024:                    }
1025:                } catch (IllegalStateException ex) {
1026:                    String projectName = ProjectUtils.getInformation(project)
1027:                            .getDisplayName();
1028:                    DialogDisplayer.getDefault().notify(
1029:                            new NotifyDescriptor.Message(NbBundle.getMessage(
1030:                                    getClass(),
1031:                                    "MSG_NoTestFolderFoundInProject",//NOI18N
1032:                                    projectName),
1033:                                    NotifyDescriptor.WARNING_MESSAGE));
1034:                    return false;
1035:                }
1036:
1037:                if (junitVer != null) {
1038:                    switch (junitVer) {
1039:                    case JUNIT3:
1040:                        return true;
1041:                    case JUNIT4:
1042:                        String sourceLevel = TestUtil
1043:                                .getSourceLevel(selectedFiles[0]);
1044:                        if (sourceLevel == null) { //could not get source level
1045:                            return true;
1046:                        }
1047:
1048:                        if (sourceLevel.compareTo("1.5") >= 0) { //NOI18N
1049:                            return true;
1050:                        } else if (askUserLastWasJUnit4NowSource14(sourceLevel)) {
1051:                            junitVer = JUnitVersion.JUNIT3;
1052:                            if (storeSettings) {
1053:                                storeProjectSettingsJUnitVer(project);
1054:                            }
1055:                            return true;
1056:                        }
1057:                        return false;
1058:                    default:
1059:                        assert false;
1060:                        return false;
1061:                    }
1062:                }
1063:
1064:                readSystemSettingsJUnitVer();
1065:                if (junitVer != null) {
1066:                    switch (junitVer) {
1067:                    case JUNIT3:
1068:                        if (storeSettings) {
1069:                            storeProjectSettingsJUnitVer(project);
1070:                        }
1071:                        return true;
1072:                    case JUNIT4:
1073:                        String sourceLevel = TestUtil
1074:                                .getSourceLevel(selectedFiles[0]);
1075:                        if ((sourceLevel != null)
1076:                                && (sourceLevel.compareTo("1.5")) >= 0) { //NOI18N
1077:                            if (storeSettings) {
1078:                                storeProjectSettingsJUnitVer(project);
1079:                            }
1080:                            return true;
1081:                        } else if (sourceLevel == null) {
1082:                            String msgKey = "MSG_select_junit_version_srclvl_unknown";//NOI18N
1083:                            junitVer = askUserWhichJUnitToUse(msgKey, true,
1084:                                    true);
1085:                            if ((junitVer != null) && storeSettings) {
1086:                                storeProjectSettingsJUnitVer(project);
1087:                            }
1088:                            return (junitVer != null);
1089:                        } else if (informUserOnlyJUnit3Applicable(sourceLevel)) {
1090:                            junitVer = JUnitVersion.JUNIT3;
1091:                            if (storeSettings) {
1092:                                storeProjectSettingsJUnitVer(project);
1093:                            }
1094:                            return true;
1095:                        }
1096:                        return false;
1097:                    default:
1098:                        assert false;
1099:                        return false;
1100:                    }
1101:                }
1102:
1103:                String msgKey;
1104:                boolean offerJUnit4;
1105:                boolean showSourceLevelReqs;
1106:                String sourceLevel = TestUtil.getSourceLevel(selectedFiles[0]);
1107:                if (sourceLevel == null) {
1108:                    msgKey = "MSG_select_junit_version_srclvl_unknown"; //NOI18N
1109:                    offerJUnit4 = true;
1110:                    showSourceLevelReqs = true;
1111:                } else {
1112:                    msgKey = "MSG_select_junit_version"; //NOI18N
1113:                    offerJUnit4 = (sourceLevel.compareTo("1.5") >= 0); //NOI18N
1114:                    showSourceLevelReqs = !offerJUnit4;
1115:                }
1116:                junitVer = askUserWhichJUnitToUse(msgKey, offerJUnit4,
1117:                        showSourceLevelReqs);
1118:                if ((junitVer != null) && storeSettings) {
1119:                    storeProjectSettingsJUnitVer(project);
1120:                }
1121:                return (junitVer != null);
1122:            }
1123:
1124:            /**
1125:             */
1126:            private boolean askUserLastWasJUnit4NowSource14(String sourceLevel) {
1127:                assert EventQueue.isDispatchThread();
1128:
1129:                JComponent msg = createMessageComponent(
1130:                        "MSG_last_was_junit4_what_now", //NOI18N
1131:                        sourceLevel);
1132:                Object selectOption = NbBundle.getMessage(getClass(),
1133:                        "LBL_create_junit3_tests"); //NOI18N
1134:                Object answer = DialogDisplayer.getDefault().notify(
1135:                        new DialogDescriptor(
1136:                                wrapDialogContent(msg),
1137:                                NbBundle.getMessage(getClass(),
1138:                                        "LBL_title_cannot_use_junit4"), //NOI18N
1139:                                true, new Object[] { selectOption,
1140:                                        CANCEL_OPTION }, selectOption,
1141:                                DialogDescriptor.DEFAULT_ALIGN, (HelpCtx) null,
1142:                                (ActionListener) null));
1143:
1144:                return answer == selectOption;
1145:            }
1146:
1147:            /**
1148:             */
1149:            private boolean informUserOnlyJUnit3Applicable(String sourceLevel) {
1150:                assert EventQueue.isDispatchThread();
1151:
1152:                JComponent msg = createMessageComponent(
1153:                        "MSG_cannot_use_default_junit4", //NOI18N
1154:                        sourceLevel);
1155:                //        Object selectOption = NbBundle.getMessage(
1156:                //                                    getClass(),
1157:                //                                    "LBL_create_junit3_tests");         //NOI18N
1158:                JButton button = new JButton();
1159:                Mnemonics.setLocalizedText(button, bundle
1160:                        .getString("LBL_Select"));
1161:                button.getAccessibleContext().setAccessibleName(
1162:                        "AN_create_junit3_tests");
1163:                button.getAccessibleContext().setAccessibleDescription(
1164:                        "AD_create_junit3_tests");
1165:
1166:                Object answer = DialogDisplayer.getDefault().notify(
1167:                        new DialogDescriptor(
1168:                                wrapDialogContent(msg),
1169:                                NbBundle.getMessage(getClass(),
1170:                                        "LBL_title_cannot_use_junit4"), //NOI18N
1171:                                true, //modal
1172:                                new Object[] { button, CANCEL_OPTION }, button,
1173:                                DialogDescriptor.DEFAULT_ALIGN, (HelpCtx) null,
1174:                                (ActionListener) null));
1175:
1176:                return answer == button;
1177:            }
1178:
1179:            //    private String getText(String bundleKey) {
1180:            //        return NbBundle.getMessage(getClass(), bundleKey);
1181:            //    }
1182:
1183:            /**
1184:             */
1185:            private JUnitVersion askUserWhichJUnitToUse(String msgKey,
1186:                    boolean offerJUnit4, boolean showSourceLevelCondition) {
1187:                assert EventQueue.isDispatchThread();
1188:
1189:                JRadioButton rbtnJUnit3 = new JRadioButton();
1190:                Mnemonics.setLocalizedText(rbtnJUnit3, bundle
1191:                        .getString("LBL_JUnit3_generator"));
1192:                rbtnJUnit3.getAccessibleContext().setAccessibleDescription(
1193:                        bundle.getString("AD_JUnit3_generator"));
1194:
1195:                JRadioButton rbtnJUnit4 = new JRadioButton();
1196:                Mnemonics.setLocalizedText(rbtnJUnit4,
1197:                        showSourceLevelCondition ? bundle
1198:                                .getString("LBL_JUnit4_generator_reqs") //NOI18N
1199:                                : bundle.getString("LBL_JUnit4_generator")); //NOI18N
1200:                rbtnJUnit4.getAccessibleContext().setAccessibleDescription(
1201:                        bundle.getString("AD_JUnit4_generator"));
1202:
1203:                ButtonGroup group = new ButtonGroup();
1204:                group.add(rbtnJUnit3);
1205:                group.add(rbtnJUnit4);
1206:
1207:                if (offerJUnit4) {
1208:                    rbtnJUnit4.setSelected(true);
1209:                } else {
1210:                    rbtnJUnit3.setSelected(true);
1211:                    rbtnJUnit4.setEnabled(false);
1212:                }
1213:
1214:                JComponent msg = createMessageComponent(msgKey);
1215:
1216:                JPanel choicePanel = new JPanel(new GridLayout(0, 1, 0, 3));
1217:                choicePanel.add(rbtnJUnit3);
1218:                choicePanel.add(rbtnJUnit4);
1219:
1220:                JPanel panel = new JPanel(new BorderLayout(0, 12));
1221:                panel.add(msg, BorderLayout.NORTH);
1222:                panel.add(choicePanel, BorderLayout.CENTER);
1223:
1224:                JButton button = new JButton();
1225:                Mnemonics.setLocalizedText(button, bundle
1226:                        .getString("LBL_Select"));
1227:                button.getAccessibleContext().setAccessibleName("AN_Select");
1228:                button.getAccessibleContext().setAccessibleDescription(
1229:                        "AD_Select");
1230:
1231:                //        Object selectOption = bundle.getString("LBL_Select");        //NOI18N
1232:                Object answer = DialogDisplayer
1233:                        .getDefault()
1234:                        .notify(
1235:                                new DialogDescriptor(
1236:                                        wrapDialogContent(panel),
1237:                                        bundle
1238:                                                .getString("LBL_title_select_generator"),//NOI18N
1239:                                        true,
1240:                                        new Object[] { button, CANCEL_OPTION },
1241:                                        button,
1242:                                        DialogDescriptor.DEFAULT_ALIGN,
1243:                                        new HelpCtx(
1244:                                                "org.netbeans.modules.junit.select_junit_version"),//NOI18N
1245:                                        (ActionListener) null));
1246:
1247:                if (answer == button) {
1248:                    JUnitVersion ver;
1249:                    if (rbtnJUnit3.isSelected()) {
1250:                        ver = JUnitVersion.JUNIT3;
1251:                    } else if (rbtnJUnit4.isSelected()) {
1252:                        ver = JUnitVersion.JUNIT4;
1253:                    } else {
1254:                        assert false;
1255:                        ver = null;
1256:                    }
1257:                    return ver;
1258:                } else {
1259:                    return null;
1260:                }
1261:            }
1262:
1263:            /**
1264:             */
1265:            private JComponent createMessageComponent(String msgKey,
1266:                    String... args) {
1267:                String message = NbBundle.getMessage(getClass(), msgKey, args);
1268:
1269:                return GuiUtils.createMultilineLabel(message);
1270:            }
1271:
1272:            /**
1273:             */
1274:            private static JComponent wrapDialogContent(JComponent comp) {
1275:                return wrapDialogContent(comp, true);
1276:            }
1277:
1278:            /**
1279:             */
1280:            private static JComponent wrapDialogContent(JComponent comp,
1281:                    boolean selfResizing) {
1282:                JComponent result;
1283:
1284:                if ((comp.getBorder() != null) || selfResizing) {
1285:                    result = selfResizing ? new SelfResizingPanel()
1286:                            : new JPanel();
1287:                    result.setLayout(new GridLayout());
1288:                    result.add(comp);
1289:                } else {
1290:                    result = comp;
1291:                }
1292:                result.setBorder(BorderFactory
1293:                        .createEmptyBorder(12, 12, 12, 12));
1294:                result.getAccessibleContext().setAccessibleDescription(
1295:                        bundle.getString("AD_title_select_generator"));
1296:                return result;
1297:            }
1298:
1299:            /**
1300:             * Gets JUnit version info from the project and stores it
1301:             * into field {@link #junitVer}.
1302:             * If the &quot;junit version&quot; info is not available,
1303:             * {@code null} is stored.
1304:             *
1305:             * @param  project  project from which the information is to be obtained
1306:             * @return  {@code true} of the set of project's libraries could be
1307:             *          determined, {@code false} if it could not be determined
1308:             * @exception  java.lang.IllegalStateException
1309:             *             if the project does not contain any test folders
1310:             * @see  #junitVer
1311:             */
1312:            private boolean readProjectSettingsJUnitVer(Project project)
1313:                    throws IllegalStateException {
1314:                assert project != null;
1315:                if (LOG_JUNIT_VER.isLoggable(FINER)) {
1316:                    LOG_JUNIT_VER.finer("readProjectSettingsJUnitVer(" //NOI18N
1317:                            + ProjectUtils.getInformation(project)
1318:                                    .getDisplayName() + ')');
1319:                }
1320:
1321:                junitVer = null;
1322:
1323:                final boolean hasJUnit3;
1324:                final boolean hasJUnit4;
1325:                final ClassPath classPath = getTestClassPath(project); //may throw ISE
1326:                if (classPath != null) {
1327:                    hasJUnit3 = (classPath.findResource(JUNIT3_SPECIFIC) != null);
1328:                    hasJUnit4 = (classPath.findResource(JUNIT4_SPECIFIC) != null);
1329:                } else {
1330:                    hasJUnit3 = false;
1331:                    hasJUnit4 = false;
1332:                }
1333:
1334:                if (hasJUnit3 != hasJUnit4) {
1335:                    junitVer = hasJUnit3 ? JUnitVersion.JUNIT3
1336:                            : JUnitVersion.JUNIT4;
1337:                    if (LOG_JUNIT_VER.isLoggable(FINEST)) {
1338:                        LOG_JUNIT_VER.finest(" - detected version " + junitVer);//NOI18N
1339:                    }
1340:                } else {
1341:                    LOG_JUNIT_VER.finest(" - no version detected"); //NOI18N
1342:                }
1343:                return (classPath != null);
1344:            }
1345:
1346:            /**
1347:             * Finds classpath used for compilation of tests.
1348:             * 
1349:             * @param  project  project whose classpath should be found
1350:             * @return  test classpath of the given project, or {@code null} if it could
1351:             *          not be determined
1352:             * @exception  java.lang.IllegalStateException
1353:             *             if no test folders were found in the project
1354:             */
1355:            private static ClassPath getTestClassPath(final Project project)
1356:                    throws IllegalStateException {
1357:                assert project != null;
1358:                if (LOG_JUNIT_VER.isLoggable(FINER)) {
1359:                    LOG_JUNIT_VER.finer("getTestClassPath(" //NOI18N
1360:                            + ProjectUtils.getInformation(project)
1361:                                    .getDisplayName() + ')');
1362:                }
1363:
1364:                final Collection<FileObject> testFolders = Utils
1365:                        .getTestFolders(project);
1366:                if (testFolders.isEmpty()) {
1367:                    LOG_JUNIT_VER.finest(" - no test folders found"); //NOI18N
1368:                    throw new IllegalStateException();
1369:                }
1370:
1371:                final ClassPathProvider cpProvider = project.getLookup()
1372:                        .lookup(ClassPathProvider.class);
1373:                if (cpProvider == null) {
1374:                    LOG_JUNIT_VER.finest(" - ClassPathProvider not found"); //NOI18N
1375:                    return null;
1376:                }
1377:
1378:                for (FileObject testRoot : testFolders) {
1379:                    ClassPath testClassPath = cpProvider.findClassPath(
1380:                            testRoot, COMPILE);
1381:                    if (testClassPath != null) {
1382:                        if (LOG_JUNIT_VER.isLoggable(FINEST)) {
1383:                            LOG_JUNIT_VER.finest(" - returning: " //NOI18N
1384:                                    + testClassPath);
1385:                        }
1386:                        return testClassPath;
1387:                    }
1388:                }
1389:
1390:                LOG_JUNIT_VER.finest(" - no compile classpath for tests found");//NOI18N
1391:                return null;
1392:            }
1393:
1394:            /**
1395:             * Stores JUnit version to the project's configuration file.
1396:             *
1397:             * @param  project  project whose configuration file is to be checked
1398:             * @see  #junitVer
1399:             */
1400:            private void storeProjectSettingsJUnitVer(final Project project) {
1401:                assert junitVer != null;
1402:
1403:                if (LOG_JUNIT_VER.isLoggable(FINER)) {
1404:                    LOG_JUNIT_VER.finer("storeProjectSettignsJUnitVer(" //NOI18N
1405:                            + ProjectUtils.getInformation(project)
1406:                                    .getDisplayName() + ')');
1407:                }
1408:
1409:                final boolean hasJUnit3;
1410:                final boolean hasJUnit4;
1411:                final ClassPath classPath = getTestClassPath(project);
1412:                if (classPath != null) {
1413:                    hasJUnit3 = (classPath.findResource(JUNIT3_SPECIFIC) != null);
1414:                    hasJUnit4 = (classPath.findResource(JUNIT4_SPECIFIC) != null);
1415:                } else {
1416:                    hasJUnit3 = false;
1417:                    hasJUnit4 = false;
1418:                }
1419:
1420:                final Pattern pattern = Pattern
1421:                        .compile("^junit(?:_|\\W)+([34])(?:\\b|_).*"); //NOI18N
1422:
1423:                JUnitLibraryComparator libraryComparator = null;
1424:
1425:                Library libraryToAdd = null;
1426:                Collection<Library> librariesToRemove = null;
1427:
1428:                LOG_JUNIT_VER.finest(" - checking libraries:"); //NOI18N
1429:                Library[] libraries = LibraryManager.getDefault()
1430:                        .getLibraries();
1431:                for (Library library : libraries) {
1432:                    String name = library.getName().toLowerCase();
1433:                    if (LOG_JUNIT_VER.isLoggable(FINEST)) {
1434:                        LOG_JUNIT_VER.finest("    " + name);
1435:                    }
1436:                    if (!name.startsWith("junit")) { //NOI18N
1437:                        LOG_JUNIT_VER.finest("     - not a JUnit library"); //NOI18N
1438:                        continue;
1439:                    }
1440:
1441:                    boolean add = false;
1442:                    boolean remove = false;
1443:                    Matcher matcher;
1444:                    final String verNumToAdd;
1445:                    if ((junitVer == JUnitVersion.JUNIT3) && !hasJUnit3) {
1446:                        verNumToAdd = "3"; //NOI18N
1447:                    } else if ((junitVer == JUnitVersion.JUNIT4) && !hasJUnit4) {
1448:                        verNumToAdd = "4"; //NOI18N
1449:                    } else {
1450:                        verNumToAdd = null;
1451:                    }
1452:                    String verNumToRemove = (junitVer == JUnitVersion.JUNIT3) ? "4"
1453:                            : "3"; //NOI18N
1454:                    if (name.equals("junit")) { //NOI18N
1455:                        add = (verNumToAdd == "3"); //NOI18N
1456:                        remove = (verNumToRemove == "3"); //NOI18N
1457:                    } else if ((matcher = pattern.matcher(name)).matches()) {
1458:                        String verNum = matcher.group(1);
1459:                        add = verNum.equals(verNumToAdd);
1460:                        remove = verNum.equals(verNumToRemove);
1461:                    }
1462:                    if (add) {
1463:                        LOG_JUNIT_VER.finest("     - to be added"); //NOI18N
1464:                        if (libraryToAdd == null) {
1465:                            libraryToAdd = library;
1466:                        } else {
1467:                            /*
1468:                             * If there are multiple conforming libraries, we only want
1469:                             * to add one - the most recent one (i.e. having the highest
1470:                             * version number).
1471:                             */
1472:                            LOG_JUNIT_VER.finest("        - will be compared:");//NOI18N
1473:                            if (libraryComparator == null) {
1474:                                libraryComparator = new JUnitLibraryComparator();
1475:                            }
1476:                            if (libraryComparator
1477:                                    .compare(libraryToAdd, library) > 0) {
1478:                                LOG_JUNIT_VER.finest("        - it won"); //NOI18N
1479:                                libraryToAdd = library;
1480:                            } else {
1481:                                LOG_JUNIT_VER.finest("        - it lost"); //NOI18N
1482:                            }
1483:                        }
1484:                    }
1485:                    if (remove) {
1486:                        LOG_JUNIT_VER.finest("     - to be removed"); //NOI18N
1487:                        if (librariesToRemove == null) {
1488:                            librariesToRemove = new ArrayList<Library>(2);
1489:                        }
1490:                        librariesToRemove.add(library);
1491:                    }
1492:                }
1493:                if ((libraryToAdd == null) && (librariesToRemove == null)) {
1494:                    return;
1495:                }
1496:
1497:                final List<FileObject> projectArtifacts = getProjectTestArtifacts(project);
1498:                if (projectArtifacts.isEmpty()) {
1499:                    displayMessage("MSG_cannot_set_junit_ver", //NOI18N
1500:                            WARNING_MESSAGE);
1501:                    return;
1502:                }
1503:
1504:                final Library[] libsToAdd, libsToRemove;
1505:                if (libraryToAdd != null) {
1506:                    libsToAdd = new Library[] { libraryToAdd };
1507:                } else {
1508:                    libsToAdd = null;
1509:                }
1510:                if (librariesToRemove != null) {
1511:                    libsToRemove = librariesToRemove
1512:                            .toArray(new Library[librariesToRemove.size()]);
1513:                } else {
1514:                    libsToRemove = null;
1515:                }
1516:                assert (libsToAdd != null) || (libsToRemove != null);
1517:
1518:                class LibrarySetModifier implements  Runnable {
1519:                    public void run() {
1520:                        boolean modified = false;
1521:                        try {
1522:                            if (libsToAdd != null) {
1523:                                for (FileObject prjArtifact : projectArtifacts) {
1524:                                    modified |= ProjectClassPathModifier
1525:                                            .addLibraries(libsToAdd,
1526:                                                    prjArtifact, COMPILE);
1527:                                }
1528:                            }
1529:                            if (libsToRemove != null) {
1530:                                for (FileObject prjArtifact : projectArtifacts) {
1531:                                    modified |= ProjectClassPathModifier
1532:                                            .removeLibraries(libsToRemove,
1533:                                                    prjArtifact, COMPILE);
1534:                                }
1535:                            }
1536:                        } catch (UnsupportedOperationException ex) {
1537:                            String prjName = ProjectUtils.getInformation(
1538:                                    project).getDisplayName();
1539:                            ErrorManager
1540:                                    .getDefault()
1541:                                    .log(
1542:                                            WARNING,
1543:                                            "Project "
1544:                                                    + prjName //NOI18N
1545:                                                    + ": Could not modify set of JUnit libraries" //NOI18N
1546:                                                    + " - operation not supported by the project.");//NOI18N
1547:                        } catch (IOException ex) {
1548:                            ErrorManager.getDefault().notify(ERROR, ex);
1549:                        }
1550:                        if (modified) {
1551:                            try {
1552:                                ProjectManager.getDefault()
1553:                                        .saveProject(project);
1554:                            } catch (IOException ex) {
1555:                                ErrorManager.getDefault().notify(ERROR, ex);
1556:                            }
1557:                        }
1558:                    }
1559:                }
1560:                ProjectManager.mutex().writeAccess(new LibrarySetModifier());
1561:            }
1562:
1563:            /**
1564:             * Schedules displaying of a message to the event-dispatching thread.
1565:             * 
1566:             * @param  bundleKey  resource bundle key of the message
1567:             * @param  msgType  type of the message
1568:             *                  (e.g. {@code NotifyDescriptor.INFORMATION_MESSAGE})
1569:             */
1570:            private static void displayMessage(String bundleKey, int msgType) {
1571:                DialogDisplayer.getDefault().notifyLater(
1572:                        new NotifyDescriptor.Message(NbBundle.getMessage(
1573:                                DefaultPlugin.class, bundleKey), msgType));
1574:            }
1575:
1576:            /**
1577:             * Finds a project artifact used as an argument to method
1578:             * {@code ProjectClassPathModifier.removeLibraries(...)
1579:             * when modifying the set of JUnit libraries (used for tests).
1580:             * 
1581:             * @param  project  project for which the project artifact should be found
1582:             * @return  list of test project artifacts, or {@code null} an empty list
1583:             *          if no one could be determined
1584:             */
1585:            private static List<FileObject> getProjectTestArtifacts(
1586:                    final Project project) {
1587:                assert project != null;
1588:
1589:                final ClassPathProvider cpProvider = project.getLookup()
1590:                        .lookup(ClassPathProvider.class);
1591:                if (cpProvider == null) {
1592:                    Collections.<FileObject> emptyList();
1593:                }
1594:
1595:                final Collection<FileObject> testFolders = Utils
1596:                        .getTestFolders(project);
1597:                if (testFolders.isEmpty()) {
1598:                    Collections.<FileObject> emptyList();
1599:                }
1600:
1601:                List<FileObject> result = null;
1602:                for (FileObject testRoot : testFolders) {
1603:                    ClassPath testClassPath = cpProvider.findClassPath(
1604:                            testRoot, ClassPath.COMPILE);
1605:                    if (testClassPath != null) {
1606:                        if (result == null) {
1607:                            if (testFolders.size() == 1) {
1608:                                return Collections
1609:                                        .<FileObject> singletonList(testRoot);
1610:                            } else {
1611:                                result = new ArrayList<FileObject>(3);
1612:                            }
1613:                        }
1614:                        result.add(testRoot);
1615:                    }
1616:                }
1617:                return (result != null) ? result : Collections
1618:                        .<FileObject> emptyList();
1619:            }
1620:
1621:            /**
1622:             * Reads information about preferred JUnit version from the IDE settings
1623:             * and stores is into field {@link #junitVer}.
1624:             *
1625:             * @see  #junitVer
1626:             */
1627:            private void readSystemSettingsJUnitVer() {
1628:                String value = JUnitSettings.getDefault().getGenerator();
1629:                if ((value == null) || value.equals(JUNIT_GENERATOR_ASK_USER)) {
1630:                    junitVer = null;
1631:                } else {
1632:                    try {
1633:                        junitVer = Enum.valueOf(JUnitVersion.class, value
1634:                                .toUpperCase());
1635:                    } catch (IllegalArgumentException ex) {
1636:                        junitVer = null;
1637:                    }
1638:                }
1639:            }
1640:
1641:            /**
1642:             * Creates a new test class.
1643:             * 
1644:             * @param  targetRoot     <!-- //PENDING -->
1645:             * @param  testClassName  <!-- //PENDING -->
1646:             * @param  testCreator  {@code TestCreator} to be used for filling
1647:             *                      the test class template
1648:             * @param  templateDataObj  {@code DataObject} representing
1649:             *                          the test file template
1650:             * @return  the created test, or {@code null} if no test was created
1651:             */
1652:            private DataObject createEmptyTest(FileObject targetRoot,
1653:                    String testClassName, TestCreator testCreator,
1654:                    final Map<String, ? extends Object> templateParams,
1655:                    DataObject templateDataObj) {
1656:                if (testClassName == null) {
1657:                    throw new IllegalArgumentException("testClassName = null"); //NOI18N
1658:                }
1659:
1660:                DataObject testDataObj = null;
1661:                try {
1662:                    DataFolder targetFolderDataObj = DataFolder
1663:                            .findFolder(targetRoot);
1664:                    testDataObj = templateDataObj.createFromTemplate(
1665:                            targetFolderDataObj, testClassName, templateParams);
1666:
1667:                    /* fill in setup etc. according to dialog settings */
1668:                    testCreator.createEmptyTest(testDataObj.getPrimaryFile());
1669:                } catch (IOException ex) {
1670:                    ErrorManager.getDefault().notify(ex);
1671:                }
1672:                return testDataObj;
1673:            }
1674:
1675:            /**
1676:             *
1677:             */
1678:            private static CreationResults createSingleTest(
1679:                    FileObject sourceFile, String testClassName,
1680:                    final TestCreator testCreator,
1681:                    final Map<String, ? extends Object> templateParams,
1682:                    DataObject templateDataObj, ClassPath testClassPath,
1683:                    boolean skipNonTestable, List<String> parentSuite,
1684:                    ProgressIndicator progress) throws CreationError {
1685:
1686:                List<SkippedClass> nonTestable;
1687:                List<ElementHandle<TypeElement>> testable;
1688:                try {
1689:                    JavaSource javaSource = JavaSource
1690:                            .forFileObject(sourceFile);
1691:                    if (skipNonTestable) {
1692:                        nonTestable = new ArrayList<SkippedClass>();
1693:                        testable = TopClassFinder.findTestableTopClasses(
1694:                                javaSource, testCreator, nonTestable);
1695:                    } else {
1696:                        nonTestable = Collections.<SkippedClass> emptyList();
1697:                        testable = TopClassFinder.findTopClasses(javaSource);
1698:                    }
1699:                } catch (IOException ex) {
1700:                    throw new CreationError(ex);
1701:                }
1702:
1703:                CreationResults result = new CreationResults(4);
1704:                if (!nonTestable.isEmpty()) {
1705:                    result.addSkipped(nonTestable);
1706:                }
1707:                if (!testable.isEmpty()) {
1708:                    String packageName = TestUtil.getPackageName(ClassPath
1709:                            .getClassPath(sourceFile, ClassPath.SOURCE)
1710:                            .getResourceName(sourceFile, '.', false));
1711:
1712:                    /* used only if (testClassName != null): */
1713:                    boolean defClassProcessed = false;
1714:
1715:                    try {
1716:                        for (ElementHandle<TypeElement> clsToTest : testable) {
1717:                            String testResourceName;
1718:                            String srcClassNameShort = TestUtil
1719:                                    .getSimpleName(clsToTest.getQualifiedName());
1720:                            if (testClassName == null) {
1721:                                testResourceName = TestUtil
1722:                                        .getTestClassFullName(
1723:                                                srcClassNameShort, packageName);
1724:                                testClassName = testResourceName.replace('/',
1725:                                        '.');
1726:                            } else if (!defClassProcessed
1727:                                    && srcClassNameShort.equals(sourceFile
1728:                                            .getName())) {
1729:                                testResourceName = testClassName.replace('.',
1730:                                        '/');
1731:                                defClassProcessed = true;
1732:                            } else {
1733:                                if (packageName == null) {
1734:                                    packageName = TestUtil
1735:                                            .getPackageName(testClassName);
1736:                                }
1737:                                testResourceName = TestUtil
1738:                                        .getTestClassFullName(
1739:                                                srcClassNameShort, packageName);
1740:                            }
1741:
1742:                            /* find or create the test class DataObject: */
1743:                            DataObject testDataObj = null;
1744:                            FileObject testFile = testClassPath
1745:                                    .findResource(testResourceName + ".java");//NOI18N
1746:                            boolean isNew = (testFile == null);
1747:                            if (testFile == null) {
1748:                                testDataObj = createTestClass(testClassPath,
1749:                                        testResourceName, templateDataObj,
1750:                                        templateParams);
1751:                                testFile = testDataObj.getPrimaryFile();
1752:                            }
1753:
1754:                            testCreator.createSimpleTest(clsToTest, testFile,
1755:                                    isNew);
1756:                            if (testDataObj == null) {
1757:                                testDataObj = DataObject.find(testFile);
1758:                            }
1759:                            save(testDataObj);
1760:
1761:                            result.addCreated(testDataObj);
1762:                            // add the test class to the parent's suite
1763:                            if (parentSuite != null) {
1764:                                parentSuite.add(testClassName);
1765:                            }
1766:                        }
1767:                    } catch (IOException ex) { //incl. DataObjectNotFoundException
1768:                        throw new CreationError(ex);
1769:                    }
1770:                }
1771:
1772:                return result;
1773:            }
1774:
1775:            /**
1776:             *
1777:             */
1778:            private static CreationResults createTests(
1779:                    final FileObject srcFileObj, final TestCreator testCreator,
1780:                    final Map<String, ? extends Object> templateParams,
1781:                    DataObject doTestT, DataObject doSuiteT,
1782:                    final ClassPath testClassPath, List<String> parentSuite,
1783:                    ProgressIndicator progress) throws CreationError {
1784:
1785:                CreationResults results;
1786:                if (srcFileObj.isFolder()) {
1787:                    results = new CreationResults();
1788:
1789:                    List<String> mySuite = new LinkedList<String>();
1790:
1791:                    progress.setMessage(getScanningMsg(srcFileObj.getName()));
1792:
1793:                    for (FileObject childFileObj : srcFileObj.getChildren()) {
1794:                        if (progress.isCanceled()) {
1795:                            results.setAbborted();
1796:                            break;
1797:                        }
1798:                        results.combine(createTests(childFileObj, testCreator,
1799:                                templateParams, doTestT, doSuiteT,
1800:                                testClassPath, mySuite, progress));
1801:                        if (results.isAbborted()) {
1802:                            break;
1803:                        }
1804:                    }
1805:
1806:                    // if everything went ok, and the option is enabled,
1807:                    // create a suite for the folder .
1808:                    if (!results.isAbborted()
1809:                            && !mySuite.isEmpty()
1810:                            && JUnitSettings.getDefault()
1811:                                    .isGenerateSuiteClasses()) {
1812:                        createSuiteTest(srcFileObj, (String) null, testCreator,
1813:                                templateParams, doSuiteT, testClassPath,
1814:                                mySuite, parentSuite, progress);
1815:                    }
1816:                } else if (srcFileObj.isData()
1817:                        && TestUtil.isJavaFile(srcFileObj)) {
1818:                    results = createSingleTest(srcFileObj,
1819:                            (String) null, //use the default clsName
1820:                            testCreator, templateParams, doTestT,
1821:                            testClassPath, true, parentSuite, progress);
1822:                } else {
1823:                    results = CreationResults.EMPTY;
1824:                }
1825:                return results;
1826:            }
1827:
1828:            /**
1829:             *
1830:             */
1831:            private static DataObject createSuiteTest(FileObject folder,
1832:                    String suiteName, final TestCreator testCreator,
1833:                    final Map<String, ? extends Object> templateParams,
1834:                    DataObject templateDataObj, ClassPath testClassPath,
1835:                    List<String> classesToInclude, List<String> parentSuite,
1836:                    ProgressIndicator progress) throws CreationError {
1837:
1838:                // find correct package name
1839:                ClassPath cp = ClassPath.getClassPath(folder, SOURCE);
1840:                assert cp != null : "SOURCE classpath was not found for "
1841:                        + folder; //NOI18N
1842:                if (cp == null) {
1843:                    return null;
1844:                }
1845:
1846:                String pkg = cp.getResourceName(folder, '/', false);
1847:                String dotPkg = pkg.replace('/', '.');
1848:                String fullSuiteName = (suiteName != null) ? pkg + '/'
1849:                        + suiteName : TestUtil.convertPackage2SuiteName(pkg);
1850:
1851:                String classNames = makeListOfClasses(classesToInclude, null);
1852:                String classes = makeListOfClasses(classesToInclude, ".class"); //NOI18N
1853:
1854:                final Map<String, Object> suiteTemplParams = new HashMap<String, Object>(
1855:                        templateParams);
1856:                suiteTemplParams.put(templatePropClassNames, classNames);
1857:                suiteTemplParams.put(templatePropClasses, classes);
1858:
1859:                try {
1860:                    /* find or create the test class DataObject: */
1861:                    DataObject testDataObj = null;
1862:                    FileObject testFile = testClassPath
1863:                            .findResource(fullSuiteName + ".java"); //NOI18N
1864:                    boolean isNew = (testFile == null);
1865:                    if (testFile == null) {
1866:                        testDataObj = createTestClass(testClassPath,
1867:                                fullSuiteName, templateDataObj,
1868:                                suiteTemplParams);
1869:                        testFile = testDataObj.getPrimaryFile();
1870:                    }
1871:
1872:                    //            List<String> processedClasses;
1873:                    //            JavaSource testSrc = JavaSource.forFileObject(testFile);
1874:                    try {
1875:                        //                processedClasses = testCreator.createTestSuite(classesToInclude,
1876:                        //                                                               testSrc,
1877:                        //                                                               isNew);
1878:                        if (testDataObj == null) {
1879:                            testDataObj = DataObject.find(testFile);
1880:                        }
1881:                        save(testDataObj);
1882:                    } catch (Exception ex) {
1883:                        ErrorManager.getDefault()
1884:                                .notify(ErrorManager.ERROR, ex);
1885:                        return null;
1886:                    }
1887:
1888:                    // add the suite class to the list of members of the parent
1889:                    //            if ((parentSuite != null) && !processedClasses.isEmpty()) {
1890:                    //                for (String simpleClassName : processedClasses) {
1891:                    //                    parentSuite.add(dotPkg.length() != 0
1892:                    //                                    ? dotPkg + '.' + simpleClassName
1893:                    //                                    : simpleClassName);
1894:                    //                }
1895:                    //            }
1896:                    return testDataObj;
1897:                } catch (IOException ioe) {
1898:                    throw new CreationError(ioe);
1899:                }
1900:            }
1901:
1902:            /**
1903:             * Makes a string contaning comma-separated list of the given names.
1904:             * If the {@code suffix} parameter is non-{@code null}, each of the given
1905:             * names is appended a given suffix.
1906:             * <p>
1907:             * Examples:
1908:             * <pre>
1909:             *     makeListOfClasses(<"Alpha", "Beta", "Gamma">, null)
1910:             *         =&gt; "Alpha,Beta,Gamma"
1911:             *     makeListOfClasses(<"Alpha", "Beta", "Gamma">, ".class")
1912:             *         =&gt; "Alpha.class,Beta.class,Gamma.class"
1913:             * </pre>
1914:             */
1915:            private static final String makeListOfClasses(
1916:                    final List<String> clsNames, final String suffix) {
1917:                if (clsNames.isEmpty()) {
1918:                    return ""; //NOI18N
1919:                }
1920:
1921:                if (clsNames.size() == 1) {
1922:                    return (suffix == null) ? clsNames.get(0) : clsNames.get(0)
1923:                            + suffix;
1924:                }
1925:
1926:                StringBuilder buf = new StringBuilder(128);
1927:                boolean first = true;
1928:                for (String clsName : clsNames) {
1929:                    if (!first) {
1930:                        buf.append(',');
1931:                    }
1932:                    buf.append(clsName);
1933:                    if (suffix != null) {
1934:                        buf.append(suffix);
1935:                    }
1936:                    first = false;
1937:                }
1938:                return buf.toString();
1939:            }
1940:
1941:            /**
1942:             *
1943:             */
1944:            public DataObject createSuiteTest(
1945:                    final FileObject targetRootFolder,
1946:                    final FileObject targetFolder, final String suiteName,
1947:                    final Map<CreateTestParam, Object> params) {
1948:                return createSuiteTest(targetRootFolder, targetFolder,
1949:                        suiteName, params, createTemplateParams(params));
1950:            }
1951:
1952:            /**
1953:             *
1954:             */
1955:            public DataObject createSuiteTest(
1956:                    final FileObject targetRootFolder,
1957:                    final FileObject targetFolder, final String suiteName,
1958:                    final Map<CreateTestParam, Object> params,
1959:                    final Map<String, ? extends Object> templateParams) {
1960:                TestCreator testCreator = new TestCreator(params, junitVer);
1961:                ClassPath testClassPath = ClassPathSupport
1962:                        .createClassPath(new FileObject[] { targetRootFolder });
1963:                List<String> testClassNames = TestUtil.getJavaFileNames(
1964:                        targetFolder, testClassPath);
1965:
1966:                final String templateId;
1967:                switch (junitVer) {
1968:                case JUNIT3:
1969:                    templateId = "PROP_junit3_testClassTemplate"; //NOI18N
1970:                    break;
1971:                case JUNIT4:
1972:                    templateId = "PROP_junit4_testClassTemplate"; //NOI18N
1973:                    break;
1974:                default:
1975:                    assert false;
1976:                    templateId = null;
1977:                    break;
1978:                }
1979:                final DataObject doSuiteTempl = loadTestTemplate(templateId);
1980:                if (doSuiteTempl == null) {
1981:                    return null;
1982:                }
1983:
1984:                DataObject suiteDataObj;
1985:                try {
1986:                    return createSuiteTest(targetFolder, suiteName,
1987:                            testCreator, templateParams, doSuiteTempl,
1988:                            testClassPath, new LinkedList<String>(
1989:                                    testClassNames), null, //parent suite
1990:                            null); //progress indicator
1991:                } catch (CreationError ex) {
1992:                    return null;
1993:                }
1994:            }
1995:
1996:            /**
1997:             */
1998:            private static DataObject createTestClass(ClassPath cp,
1999:                    String testClassName, DataObject templateDataObj,
2000:                    final Map<String, ? extends Object> templateParams)
2001:                    throws DataObjectNotFoundException, IOException {
2002:
2003:                assert cp.getRoots().length == 1;
2004:                FileObject root = cp.getRoots()[0];
2005:                int index = testClassName.lastIndexOf('/');
2006:                String pkg = index > -1 ? testClassName.substring(0, index)
2007:                        : ""; //NOI18N
2008:                String clazz = index > -1 ? testClassName.substring(index + 1)
2009:                        : testClassName;
2010:
2011:                // create package if it does not exist
2012:                if (pkg.length() > 0) {
2013:                    root = FileUtil.createFolder(root, pkg); //IOException
2014:                }
2015:                // instantiate template into the package
2016:                return templateDataObj.createFromTemplate( //IOException
2017:                        DataFolder.findFolder(root), clazz, templateParams);
2018:            }
2019:
2020:            /**
2021:             *
2022:             */
2023:            private static void save(DataObject dataObj) throws IOException {
2024:                SaveCookie sc = dataObj.getCookie(SaveCookie.class);
2025:                if (null != sc) {
2026:                    sc.save();
2027:                }
2028:            }
2029:
2030:            /**
2031:             * Loads a test template.
2032:             * If the template loading fails, displays an error message.
2033:             *
2034:             * @param  templateID  bundle key identifying the template type
2035:             * @return  loaded template, or <code>null</code> if the template
2036:             *          could not be loaded
2037:             */
2038:            private static DataObject loadTestTemplate(String templateID) {
2039:                // get the Test class template
2040:                String path = NbBundle.getMessage(DefaultPlugin.class,
2041:                        templateID);
2042:                try {
2043:                    FileObject fo = Repository.getDefault()
2044:                            .getDefaultFileSystem().findResource(path);
2045:                    if (fo == null) {
2046:                        noTemplateMessage(path);
2047:                        return null;
2048:                    }
2049:                    return DataObject.find(fo);
2050:                } catch (DataObjectNotFoundException e) {
2051:                    noTemplateMessage(path);
2052:                    return null;
2053:                }
2054:            }
2055:
2056:            /**
2057:             *
2058:             */
2059:            private static void noTemplateMessage(String temp) {
2060:                String msg = NbBundle.getMessage(CreateTestAction.class,
2061:                        "MSG_template_not_found", //NOI18N
2062:                        temp);
2063:                NotifyDescriptor descr = new NotifyDescriptor.Message(msg,
2064:                        NotifyDescriptor.ERROR_MESSAGE);
2065:                DialogDisplayer.getDefault().notify(descr);
2066:            }
2067:
2068:            /**
2069:             * A helper method to create the reason string from a result
2070:             * and two message bundle keys that indicate the separators to be used instead
2071:             * of "," and " and " in a connected reason like: 
2072:             * "abstract, package-private and without testable methods".
2073:             * <p>
2074:             * The values of the keys are expected to be framed by two extra characters
2075:             * (e.g. as in " and "), which are stripped off. These characters serve to 
2076:             * preserve the spaces in the properties file.
2077:             *
2078:             * @param reason the TestabilityResult to represent
2079:             * @param commaKey bundle key for the connective to be used instead of ", "
2080:             * @param andKey   bundle key for the connective to be used instead of "and"
2081:             * @return String composed of the reasons contained in
2082:             *         <code>reason</code> separated by the values of commaKey and
2083:             *         andKey.
2084:             */
2085:            private static String strReason(TestabilityResult reason,
2086:                    String commaKey, String andKey) {
2087:                String strComma = NbBundle.getMessage(CreateTestAction.class,
2088:                        commaKey);
2089:                String strAnd = NbBundle.getMessage(CreateTestAction.class,
2090:                        andKey);
2091:                String strReason = reason.getReason( // string representation of the reasons
2092:                        strComma.substring(1, strComma.length() - 1), strAnd
2093:                                .substring(1, strAnd.length() - 1));
2094:
2095:                return strReason;
2096:
2097:            }
2098:
2099:            /**
2100:             *
2101:             */
2102:            private static String getCreatingMsg(String className) {
2103:                return NbBundle.getMessage(DefaultPlugin.class,
2104:                        "FMT_generator_status_creating", //NOI18N
2105:                        className);
2106:            }
2107:
2108:            /**
2109:             *
2110:             */
2111:            private static String getScanningMsg(String sourceName) {
2112:                return NbBundle.getMessage(DefaultPlugin.class,
2113:                        "FMT_generator_status_scanning", //NOI18N
2114:                        sourceName);
2115:            }
2116:
2117:            /**
2118:             *
2119:             */
2120:            private static String getIgnoringMsg(String sourceName,
2121:                    String reason) {
2122:                return NbBundle.getMessage(DefaultPlugin.class,
2123:                        "FMT_generator_status_ignoring", //NOI18N
2124:                        sourceName);
2125:            }
2126:
2127:            /**
2128:             * Error thrown by failed test creation.
2129:             */
2130:            @SuppressWarnings("serial")
2131:            private static final class CreationError extends Exception {
2132:                CreationError() {
2133:                };
2134:
2135:                CreationError(Throwable cause) {
2136:                    super (cause);
2137:                }
2138:            }
2139:
2140:            /**
2141:             * Utility class representing the results of a test creation
2142:             * process. It gatheres all tests (as DataObject) created and all
2143:             * classes (as JavaClasses) for which no test was created.
2144:             */
2145:            static final class CreationResults {
2146:                static final CreationResults EMPTY = new CreationResults();
2147:
2148:                Set<DataObject> created; // Set< createdTest : DataObject >
2149:                Set<SkippedClass> skipped;
2150:                boolean abborted = false;
2151:
2152:                CreationResults() {
2153:                    this (20);
2154:                }
2155:
2156:                CreationResults(int expectedSize) {
2157:                    created = new HashSet<DataObject>(expectedSize * 2, 0.5f);
2158:                    skipped = new HashSet<SkippedClass>(expectedSize * 2, 0.5f);
2159:                }
2160:
2161:                void setAbborted() {
2162:                    abborted = true;
2163:                }
2164:
2165:                /**
2166:                 * Returns true if the process of creation was abborted. The
2167:                 * result contains the results gathered so far.
2168:                 */
2169:                boolean isAbborted() {
2170:                    return abborted;
2171:                }
2172:
2173:                /**
2174:                 * Adds a new entry to the set of created tests.
2175:                 * @return true if it was added, false if it was present before
2176:                 */
2177:                boolean addCreated(DataObject test) {
2178:                    return created.add(test);
2179:                }
2180:
2181:                /**
2182:                 */
2183:                boolean addSkipped(SkippedClass skippedClass) {
2184:                    return skipped.add(skippedClass);
2185:                }
2186:
2187:                /**
2188:                 */
2189:                void addSkipped(Collection<SkippedClass> skippedClasses) {
2190:                    if (!skippedClasses.isEmpty()) {
2191:                        skipped.addAll(skippedClasses);
2192:                    }
2193:                }
2194:
2195:                /**
2196:                 * Returns a set of classes that were skipped in the process.
2197:                 * @return Set<SkippedClass>
2198:                 */
2199:                Set<SkippedClass> getSkipped() {
2200:                    return skipped;
2201:                }
2202:
2203:                /**
2204:                 * Returns a set of test data objects created.
2205:                 * @return Set<DataObject>
2206:                 */
2207:                Set<DataObject> getCreated() {
2208:                    return created;
2209:                }
2210:
2211:                /**
2212:                 * Combines two results into one. If any of the results is an
2213:                 * abborted result, the combination is also abborted. The
2214:                 * collections of created and skipped classes are unified.
2215:                 * @param rhs the other CreationResult to combine into this
2216:                 */
2217:                void combine(CreationResults rhs) {
2218:                    if (rhs.abborted) {
2219:                        this .abborted = true;
2220:                    }
2221:
2222:                    this.created.addAll(rhs.created);
2223:                    this.skipped.addAll(rhs.skipped);
2224:                }
2225:
2226:            }
2227:
2228:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.